A few days ago, I wrote about issues with implementing a ListView in ASP.NET. Now, with all of the other code written, I’m having trouble saving changed items in a ListView.
A few things of note:
- The Save button is not part of the ListView proper; it calls the
GetListViewItems()method, which in turns call theSave()method. - The
Listview.DataBind()event is invoked when a button is pressed requesting the records to be updated - The Listview shows text using
<%#Eval("Key.Name") %>and a namedDropDownListusing<%#Eval("Value") %>
Getting The Items From the 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 the ListView
The code to databind the ListView is shown here in my previous question.
Question(s):
- Why is it that when I iterate through the
ListViewDataItemin theListviewthat each item isnull? - How can I retrieve the
Foo.Idfrom the Dictionary? - What else might I be missing?
- What would I use if I wanted to get that
IdProgrammatically based on what items were shown? As it is now, the current ListView is shown based on whatFoos were selected. ThoseFoos selected are then displayed, and the user can change theBarin theDropDownList, hit Save, and those changes are propogated.
Update
As it turns out, my problem was what leppie had said; and that was that I needed to specify DataKeyNames and use those to retain the information from the ListView.
Here’s the code I added:
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++;
}
}
}
And then in the .ascx file, I added DataKeyNames="Key", like so:
<asp:ListView ID="lvFooList" runat="server" DataKeyNames="Key">
This allowed me to use the Key from my previous post to determine which Foo was being looked at.
Any critiques of this approach, as well as methods for making it better are greatly appreciated.
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
Some quick answers:
-
Your need to use databinding for that to work, in other words, assign to
DataSourceand callDataBind(). EDIT: seems you are doing that. But remember it wont persist between postbacks, just theDataKey(see below). -
If I recall correctly, you need to specify the
DataKeyNames, and they can be retrieved from theDataKeyproperty then.
Method 2
you can also use the ListViewDataItem.DataItemIndex property instead of keeping your own index, as in:
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
}
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0