ListView DataItem mostra nulo
Pergunta
Alguns dias atrás, eu escreveu sobre questões com a implementação de um ListView em ASP.NET. Agora, com todos os outros código escrito, estou tendo problemas para salvar itens alterados em um ListView.
Algumas coisas de nota:
- O botão Salvar não é parte do ListView adequada; ele chama o método
GetListViewItems()
, que por sua vez chama o métodoSave()
. - O evento
Listview.DataBind()
é chamado quando um botão é pressionado solicitando os registros para ser atualizado - A mostra ListView texto usando
<%#Eval("Key.Name") %>
e uma chamadoDropDownList
usando<%#Eval("Value") %>
Obtendo os itens da ListView
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
}
}
DataBinding o ListView
O código para vincular o ListView é mostrado aqui na minha pergunta anterior .
Pergunta (s):
- Por que é que quando eu percorrer a
ListViewDataItem
naListview
que cada item énull
? - Como posso recuperar o
Foo.Id
do dicionário? - O que mais eu poderia estar faltando?
- O que eu iria usar se eu queria ter que
Id
programaticamente com base em quais itens foram mostrados? Como é agora, o ListView atual é mostrada com base no que foram selecionadosFoo
s. EssesFoo
s selecionados são exibidos, eo usuário pode alterar oBar
naDropDownList
, bateu em Salvar, e essas alterações são propagada.
Atualização
Como se vê, o meu problema era o que leppie tinha dito; e que foi que eu precisava para especificar DataKeyNames
e usá-las para reter as informações do ListView.
Aqui está o código que acrescenta:
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++;
}
}
}
E, em seguida, no arquivo .ascx
, acrescentei DataKeyNames="Key"
, assim:
<asp:ListView ID="lvFooList" runat="server" DataKeyNames="Key">
Isso me permitiu usar o Key
do meu post anterior para determinar qual Foo estava sendo olhado.
Qualquer críticas desta abordagem, bem como métodos para torná-lo melhor são muito apreciados.
Solução
Algumas respostas rápidas:
-
A sua necessidade de utilização de ligação de dados para que isso funcione, ou seja, atribuir aos
DataSource
eDataBind()
chamada. EDIT: Parece que você está fazendo isso. Mas lembre-se que costuma persistir entre postbacks, apenas oDataKey
(veja abaixo). -
Se bem me lembro, você precisa especificar o
DataKeyNames
, e eles podem ser recuperados a partir da propriedadeDataKey
então.
Outras dicas
Você também pode usar a propriedade ListViewDataItem.DataItemIndex em vez de manter seu próprio índice, como em:
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
}