给出一个对象电影,该对象的电影具有作为演员列表的演员角色。如何在可折叠的层次网格中显示Actor?
RadGrid声明:
<telerik:RadGrid ID="RadGrid1" runat="server">
<MasterTableView PageSize="10" DataKeyNames="Actors" GroupsDefaultExpanded="False">
<DetailTables>
<telerik:GridTableView >
</telerik:GridTableView>
</DetailTables>
</MasterTableView>
</telerik:RadGrid>
在后面的代码中:
RadGrid1.DataSource = ServiceLike.GetMovies();
public class Movie
{
public int Id { get; set; }
public string Title { get; set; }
public string Genres { get; set; }
public Actor[] Actors { get; set; }
}
public class Actor
{
public string Name { get; set; }
}
public static class ServiceLike
{
public static Movie[] GetMovies()
{
return new[]{
new Movie{
Id =1,
Genres ="",
Title ="First",
Actors= new []{
new Actor{ Name= "Actor1" },
}
},
new Movie{Id=2, Genres="", Title="Second",
Actors= new []{
new Actor{ Name= "Foo" },
new Actor{ Name= "Bar" },
}
},
new Movie{Id=3, Genres="", Title="Third",
Actors= new []{
new Actor{ Name= "Joe" },
new Actor{ Name= "Monika" },
new Actor{ Name= "Ross" },
}
},
};
}
}
这里的目的是将调用限制在DetailTable中的GetMovies()
方法上。
这是我的问题的简化:将列表显示为子网格,而不向提供包含此列表的对象的服务发送垃圾邮件。电影和演员是与真实数据无关的示例类。网格声明是一个干净的尝试,由于telerik可能是很多尝试和失败,所以我提供了一个干净的尝试,而不是众多尝试中的任何尝试,因为它们可能会误导他人。
DataKeyNames只能包含Bindable Property Types。列表,数组等将不起作用。
此外,DataKeyNames旨在提供可用于标识对象的值。在这种情况下,最好使用电影ID:
<telerik:RadGrid ID="RadGrid1" runat="server"
OnNeedDataSource="RadGrid1_NeedDataSource"
OnDetailTableDataBind="RadGrid1_DetailTableDataBind">
<MasterTableView PageSize="10" DataKeyNames="Id" GroupsDefaultExpanded="False">
<DetailTables>
<telerik:GridTableView>
</telerik:GridTableView>
</DetailTables>
</MasterTableView>
</telerik:RadGrid>
当然,如果子项具有可绑定的属性,则可以将其用作唯一标识符。
DataKeyNames="Actor.Id"
如果是数组,则需要按其数组索引访问该项目。甚至可以使用多个Actor的ID来充当一行的标识符。这可能有助于按演员ID查找电影。
DataKeyNames="Actors[0].Id, Actors[1].Id, Actors[3].Id"
但是,这不切实际,如果应用程序尝试通过不存在的索引访问数组项,则该应用程序将出错。
为了避免由于绑定导致的任何意外行为,请使用Advanced Data-binding (Using NeedDataSource Event)将数据绑定到RadGrid。也许,您已经在使用它。我以防万一。
protected void RadGrid1_NeedDataSource(object sender, Telerik.Web.UI.GridNeedDataSourceEventArgs e)
{
if (!e.IsFromDetailTable) RadGrid1.DataSource = ServiceLike.GetMovies();
}
为了以编程方式将数据绑定到子表,可以使用DetailTableDataBind事件。 (Hierarchical data-binding using DetailTableDataBind event)。展开Grid行后,它将立即触发,并且在事件参数中,您将有权访问Child表对象。使用它遍历对象树并访问其父树。 (Accessing Cells and Rows)
protected void RadGrid1_DetailTableDataBind(object sender, Telerik.Web.UI.GridDetailTableDataBindEventArgs e)
{
GridTableView tableView = e.DetailTableView;
GridNestedViewItem nestedViewItem = tableView.NamingContainer as GridNestedViewItem;
GridDataItem parentItem = nestedViewItem.ParentItem;
e.DetailTableView.DataSource = Array.Find(ServiceLike.GetMovies(), item => item.Id == (int)parentItem.GetDataKeyValue("Id")).Actors;
}