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, поэтому они должны предоставлять вам только данные текущей записи.

Надеюсь, это поможет вам решить вашу проблему.

Другие вопросы по тегам