ListView в ASP.NET и DataKeyNames
У меня есть ListView, который связан со списком "A", который выглядит следующим образом:
Class A
Property Id as Integer
Property TestStringA as String
Property B as B
End Class
Class B
Property Id as Integer
Property TestStringB as String
End Class
В ListView я могу ссылаться на значения 'свойства ссылки' (какой термин подходит для этого?):
<asp:ListView runat="server" ID="lwTest" ItemType="A">
<LayoutTemplate>
<tr runat="server" id="itemPlaceHolder"></tr>
</LayoutTemplate>
<ItemTemplate>
<tr>
<td><%# Item.TestStringA %></td>
<td><%# Item.B.TestStringB %></td> (this is what I mean)
</tr>
</ItemTemplate>
</asp:ListView>
Это также работает при использовании Eval-метода (если невозможно использовать ItemType):
<%# Eval(B.TestStringB) %>
Я хочу зациклить элементы ListView и использовать значения из контейнера, не сохраняя их в скрытых полях (разве это не цель 'DataKeyNames'?). Проблема в том, что я не могу ссылаться на свойство другого объекта по его атрибуту / свойству ссылки (в примере B.Id) в DataKeyNames. Когда я делаю это, я получаю сообщение об ошибке, в котором говорится, что нет свойства с именем B.Id:
<asp:ListView runat="server" ID="lwTest" ItemType="A" DataKeyNames"Id, B.Id">
<LayoutTemplate>
<tr runat="server" id="itemPlaceHolder"></tr>
</LayoutTemplate>
<ItemTemplate>
<tr>
<td><%# Item.TestStringA %></td>
<td><%# Item.B.TestStringB %></td> (this is what I mean)
</tr>
</ItemTemplate>
</asp:ListView>
Кто-нибудь знает, возможно ли это сделать? Я знаю, что могу добавить свойства только для чтения, возвращающие значение непосредственно связанному объекту (но я хотел бы избежать этого, если это возможно):
Class A
Property Id as Integer
Property TestStringA as String
Property B as B
ReadOnly Property BId as Integer
Get
Return B.Id
End Get
End Property
End Class
Class B
Property Id as Integer
Property TestStringB as String
End Class
Заранее спасибо!
1 ответ
Прежде всего, вы можете использовать только прямые свойства класса в качестве ваших DataKeyNames. С инструкцией Eval вы можете пойти глубже (но я верю только на один уровень).
Что вы можете сделать, это изменить то, что отображается в вашем списке через код позади.
Для этого добавьте событие ItemDataBound. Данные для создаваемого элемента можно найти в конце e.Item.DataItem, будет иметь тип A (выполните приведение его перед использованием).
Вы должны иметь возможность получить доступ к своим элементам управления напрямую через e.Item (не знаю, какие свойства использовать наизусть на этом), и как только вы найдете правильную ячейку, вы можете установить для нее любой текст, какой захотите, и поскольку Имея связанный экземпляр A, вы можете вызывать любое свойство или вспомогательное свойство по вашему желанию без ограничений.
Эта функция вызывается для каждой записи в вашем ListView, поэтому они должны предоставлять вам только данные текущей записи.
Надеюсь, это поможет вам решить вашу проблему.