ListView DataItem indique Null
Question
Il y a quelques jours, j'ai écrit sur des problèmes . avec l'implémentation d'un ListView dans ASP.NET. Maintenant, avec tout le code écrit, je ne parviens pas à enregistrer les éléments modifiés dans un ListView.
Quelques points à noter:
- Le bouton Enregistrer ne fait pas partie de ListView proprement dit; il appelle la méthode
GetListViewItems()
, qui à son tour appelle la méthodeSave()
. - L'événement
Listview.DataBind()
est appelé lorsque l'utilisateur clique sur un bouton demandant la mise à jour des enregistrements - La vue en liste affiche le texte avec
<%#Eval("Key.Name") %>
et une nommée <= > avecDropDownList
Récupération des éléments de la liste
public void GetListViewItems()
{
List<Foo> Result = FooManager.CreateFooList();
DropDownList ddl = null;
ListViewItem Item = null;
try
{
foreach (ListViewDataItem item in lvFooList.Items)
{
Item = item;
ddl = ((DropDownList) (Item.FindControl("ddlListOfBars")));
if (//something is there)
{
Foo foo = FooManager.CreateFoo();
foo.Id = item.DataItemIndex; //shows null
int barId = int.Parse(ddl.SelectedItem.Value); //works just fine
foo.barId = barId;
Result.Add(foo);
}
}
}
catch (Exception ex)
{
//Irrelevant for our purposes
}
}
Liaison de données à la liste
Le code permettant de rechercher la liste dans la liste est affiché ici dans ma question précédente. .
Question (s):
- Pourquoi est-ce que, lorsque je parcours à travers le
<%#Eval("Value") %>
dans leListViewDataItem
, chaque élément estListview
? - Comment puis-je extraire le
null
du dictionnaire? - Quoi d'autre pourrais-je être absent?
- Qu'est-ce que j'utiliserais si je voulais obtenir cela
Foo.Id
par programmation en fonction des éléments affichés? À l’heure actuelle, la liste actuelle est affichée en fonction desId
s sélectionnés. LesFoo
s sélectionnés sont ensuite affichés et l'utilisateur peut modifier leBar
dansDataKeyNames
, cliquer sur Enregistrer, et ces modifications sont propagées.
Mettre à jour
En fin de compte, mon problème était ce que leppie avait dit; et c’est pour cela que je devais spécifier .ascx
et utiliser ceux-ci pour conserver les informations de ListView.
Voici le code que j'ai ajouté:
try
{
int DataKeyArrayIndex = 0;
foreach (ListViewDataItem item in lvFooList.Items)
{
Item = item;
ddl = ((DropDownList) (Item.FindControl("ddlListOfBars")));
if (//something is there)
{
Foo foo = FooManager.CreateFoo();
Foo tempFoo = FooManager.CreateFoo();
if (lvFooList != null)
{
tempFoo = ((Foo)(lvFooList.DataKeys[DataKeyArrayIndex].Value));
}
foo.Id = tempFoo.Id;
int barId = int.Parse(ddl.SelectedItem.Value); //works just fine
foo.barId = barId;
Result.Add(foo);
DataKeyArrayIndex++;
}
}
}
Et dans le fichier DataKeyNames="Key"
, j'ai ajouté Key
, comme suit:
<asp:ListView ID="lvFooList" runat="server" DataKeyNames="Key">
Cela m'a permis d'utiliser le <=> de mon précédent message. pour déterminer quel Foo était examiné.
Toutes les critiques de cette approche, ainsi que les méthodes pour la rendre meilleure, sont grandement appréciées.
La solution
Quelques réponses rapides:
-
Votre besoin d'utiliser la liaison de données pour que cela fonctionne, en d’autres termes, attribuez à
DataSource
et appelezDataBind()
. EDIT: semble que vous faites cela. Mais rappelez-vous qu'il ne persistera pas entre les publications, mais uniquement leDataKey
(voir ci-dessous). -
Si je me souviens bien, vous devez spécifier le
DataKeyNames
. Ils peuvent ensuite être extraits de la propriété <=>.
Autres conseils
vous pouvez également utiliser la propriété ListViewDataItem.DataItemIndex au lieu de conserver votre propre index, comme dans:
foreach (ListViewDataItem item in MyListView.Items)
{
// in this example key is a string value
Foo foo = new Foo(MyListView.DataKeys[item.DataItemIndex].Value as string);
// do stuff with foo
}