Это возможно, и я делал это много раз раньше.
Возможно, вам придется подключить события самостоятельно, и вам придется использовать FindControl()
в событии привязки к элементу ретранслятора, чтобы получить конкретный ListView для установки источника данных, а также для вызова DataBind для него.
Вы можете использовать ярлык привязки данных <%# ... %>
во вложенном Repeater / DataList, но не для установки источника данных, как вы сделали.
Вставьте следующее в пустой новый проект. Компилирует и запускает.
(Большой отказ от ответственности - html только для демонстрации и довольно скудный.)
Код веб-формы.
<asp:ListView ID="dlOuter" runat="server"
onitemdatabound="dlOuter_ItemDataBound">
<LayoutTemplate>
<div id="personGroupList">
<asp:PlaceHolder ID="itemPlaceHolder" runat="server" />
</div>
</LayoutTemplate>
<ItemTemplate>
<div class="groupHeading"><%# Eval("Key") %></div>
<asp:ListView ID="dlInner" runat="server"
ItemPlaceholderID="innerItemPlaceHolder"
onitemdatabound="dlInner_ItemDataBound"
>
<LayoutTemplate>
<asp:PlaceHolder ID="innerItemPlaceHolder" runat="server" />
</LayoutTemplate>
<ItemTemplate>
<div class="person">
Name: <%# Eval("Name") %>
Age: <%# Eval("Age") %>
</div>
</ItemTemplate>
</asp:ListView>
</ItemTemplate>
</asp:ListView>
Теперь в коде позади
protected void Page_Load(object sender, EventArgs e)
{
// takes a list of Person and group's by Person.City
// really this is just an outer grouping that's in use.
var query = from p in Person.GetPersons() select p;
dlOuter.DataSource = query.ToLookup(o => o.City);
dlOuter.DataBind();
}
// The outer List View is the groups.
// we bind the inner view to the list if Person in the group.
protected void dlOuter_ItemDataBound(object sender, ListViewItemEventArgs e)
{
if (e.Item.ItemType == ListViewItemType.DataItem)
{
ListViewDataItem di = (ListViewDataItem)e.Item;
ListView inner = (ListView)e.Item.FindControl("dlInner");
IGrouping<string, Person> lookup = (IGrouping<string, Person>)di.DataItem;
inner.DataSource = lookup.AsEnumerable();
inner.DataBind();
}
}
protected void dlInner_ItemDataBound(object sender, ListViewItemEventArgs e)
{
// included so you can see how it's wired up. Unused in this sample.
}
Персональный класс только для демонстрации.
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public string City { get; set; }
public static List<Person> GetPersons()
{
List<Person> persons = new List<Person>
{
new Person { Name="Bob", Age=30, City="Chicago" },
new Person { Name="Mary", Age=20, City="NYC" },
new Person { Name="Marty", Age=12, City="LA" },
new Person { Name="Fred", Age=33, City="NYC" },
new Person { Name="Susan", Age=22, City="Chicago" }
};
return persons;
}
}
Обратите внимание, что в этом примере я группирую, используя ToLookup, чтобы создать группировку из списка. В реальном коде, из которого он получен, он показывает страницу данных, упорядоченную по тому, что происходит в определенный день. Например. записи отсортированы по thing.SomeDate
, а группировка - query.ToLookup( o => o.SomeDate.ToLongDateString() );
Важно отметить, что ToLookup
и использование IGrouping<T,X>
не имеют значения, за исключением того, что мне нужно каким-то образом получить сгруппированные данные для целей примера. Вы также можете легко получить канонический пример Order
и OrderDetail
, где внешний ListView - это List<Order>
, а внутренний ListView - это Order.OrderDetails