如何基于父属性中的列表项声明Hierachic网格?

问题描述 投票:0回答:1

给出一个对象电影,该对象的电影具有作为演员列表的演员角色。如何在可折叠的层次网格中显示Actor?

例如:Img Here

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可能是很多尝试和失败,所以我提供了一个干净的尝试,而不是众多尝试中的任何尝试,因为它们可能会误导他人。

c# telerik telerik-grid
1个回答
0
投票

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;
}

如果都正确完成,结果将如下所示:enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.