ListView DataItem показывает Null
Несколько дней назад я писал о проблемах с реализацией ListView в ASP.NET. Теперь, когда весь написанный код написан, мне не удается сохранить измененные элементы в ListView.
Несколько примечаний:
- Кнопка "Сохранить" не входит в список ListView; он вызывает метод
GetListViewItems()
, который по очереди вызывает метод Save()
.
- Событие
Listview.DataBind()
вызывается при нажатии кнопки с запросом обновления записей
- Listview показывает текст, используя
<%#Eval("Key.Name") %>
и с именем DropDownList
, используя <%#Eval("Value") %>
Получение элементов из списка 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 ListView
Код для привязки списка ListView показан здесь в моем предыдущем вопросе.
Вопрос (ы):
- Почему это происходит, когда я повторяю через
ListViewDataItem
в Listview
, что каждый элемент null
?
- Как я могу получить
Foo.Id
из Словаря?
- Что еще я могу потерять?
- Что бы я использовал, если бы хотел, чтобы этот
Id
программно был основан на том, какие предметы были показаны? Как и сейчас, текущий ListView показан на основе того, что было выбрано Foo
. Затем отображаются те Foo
, и пользователь может изменить Bar
в DropDownList
, нажать "Сохранить", и эти изменения распространяются.
Update
Как выясняется, моя проблема заключалась в том, что сказал leppie; и это было то, что мне нужно было указать DataKeyNames
и использовать их для сохранения информации из ListView.
Здесь код, который я добавил:
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++;
}
}
}
И затем в файле .ascx
я добавил DataKeyNames="Key"
, например:
<asp:ListView ID="lvFooList" runat="server" DataKeyNames="Key">
Это позволило мне использовать Key
из моего предыдущего сообщения, чтобы определить, на что смотрел Foo.
Любые критические замечания по этому подходу, а также методы для его лучшего использования с благодарностью.
Ответы
Ответ 1
Несколько быстрых ответов:
-
Вам нужно использовать привязку данных для этого, другими словами, назначить DataSource
и вызвать DataBind()
. EDIT: Кажется, вы это делаете. Но помните, что он не будет сохраняться между postbacks, просто DataKey
(см. Ниже).
-
Если я правильно помню, вам нужно указать DataKeyNames
, и их можно будет получить из свойства DataKey
.
Ответ 2
вы также можете использовать свойство ListViewDataItem.DataItemIndex вместо своего собственного индекса, например:
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
}