如何动态地将列添加到 RadGrid



我有一个RadGrid,其中有未知数量的列,我想创建。 实际上我知道第一列,它的数据字段为 PermissionName . 我有一个 CSLA 数据源,它返回一个PermissionInfo对象的列表,每个对象都包含一个RoleInfo对象的列表。 当 PermissionInfo 对象具有不同数量的RoleInfo对象时,如何在 RadGrid 中为每个 RoleInfo 对象动态创建列?

如果任何 PermissionInfo 对象包含特定的 RoleInfo 对象,我想创建一个列,其中 RoleInfo.RoleName 作为标题,True 作为 DataValue。 如果RoleInfo对象不存在,那么我希望该行和列的 DataValue = false。

这是我的辐射网格:

    <telerik:RadGrid ID="rgPermissions" AllowPaging="false" AllowSorting="true" AutoGenerateColumns="false"
    DataSourceID="dsPermissions" runat="server">
    <MasterTableView DataKeyNames="PermissionId" DataSourceID="dsPermissions" EditMode="InPlace">
        <Columns>
            <telerik:GridBoundColumn DataField="PermissionName" HeaderText="Permission" ></telerik:GridBoundColumn>
        </Columns>
    </MasterTableView>
    </telerik:RadGrid>
<csla:CslaDataSource ID="dsPermissions" runat="server" OnSelectObject="dsPermissions_SelectObject">
</csla:CslaDataSource>

以下是PermissionInfo的住宿

    public int PermissionId { get; set; }
    public string PermissionName { get; set; }
    public RoleInfoList Roles { get; set; }

以下是RoleInfo的属性:

    public int RoleId { get; set; }
    public string RoleName { get; set; }
    public string Title { get; set; }

在我的page_load方法中,我还编写了一个工厂方法来检索所有角色:

RoleInfoList roles = RoleInfoList.GetRoleList();

有几种方法;首先,您可以使用 Telerik 本机支持的分层网格方法(请参阅本主题和子主题)。 或者,可以通过执行 LINQ 语句,然后绑定匿名结果来"平展"尝试绑定的结果。

var p in permissions
select new
{
    p.PermissionId,
    p.PermissionName,
    RolesList = String.Join(", ", p.Roles.Select(i => i.RoleName))
}

请注意,此方法对 LINQ 不友好,因为 Join 未转换为 LINQ。

这是我最终做的事情:我最终放弃了 CSLA 数据源,而只是绑定了一个数据表。 我从我的RadGrid中删除了静态的GridBoundColumn,因为它正在创建一个额外的列,并调用OnNeedDataSource事件:

<telerik:RadGrid ID="rgPermissions" AllowPaging="false" AllowSorting="true" OnNeedDataSource="rgPermissions_NeedDataSource"
    runat="server">
    <MasterTableView DataKeyNames="Permission Name" AutoGenerateColumns="true" EditMode="InPlace">
        <Columns>
            <telerik:GridEditCommandColumn />
        </Columns>
    </MasterTableView>
</telerik:RadGrid>

然后我填写了我的事件处理程序,使用 CSLA 工厂方法创建了 DataTable:

protected void rgPermissions_NeedDataSource(object sender, Telerik.Web.UI.GridNeedDataSourceEventArgs e)
{
    // Data Access
    PermissionInfoList permissions = PermissionInfoList.GetPermissionInfoList();
    RoleInfoList roles = RoleInfoList.GetRoleList();
    // create datatable for permissions
    DataTable permissionTable = CreatePermissionDataTable(roles);
    foreach (PermissionInfo permission in permissions)
    {
        // Add permission name
        DataRow dataRow = permissionTable.NewRow();
        dataRow["Permission Name"] = permission.PermissionName;
        AddRow(permission, permissionTable, dataRow, roles);
    }
    rgPermissions.DataSource = permissionTable;
}

我为权限数据创建了一个数据表:

private DataTable CreatePermissionDataTable(RoleInfoList roles)
{
    DataTable permissions = new DataTable();
    permissions.Columns.Add("Permission Name", typeof(string));
    permissions.Columns["Permission Name"].ReadOnly = true;
    foreach (RoleInfo role in roles)
    {
        permissions.Columns.Add(role.Title, typeof(Boolean));
    }
    return permissions;
}

我确实使用 LINQ 从角色数据中筛选出权限:

private DataTable AddRow(PermissionInfo permission, DataTable permissions, DataRow dataRow, RoleInfoList roles)
{
    // Add roles
    foreach (RoleInfo role in roles)
    {
        dataRow[role.Title] = permission.Roles.Any(r => r.RoleId == role.RoleId);
    }
    permissions.Rows.Add(dataRow);
    return permissions;
}

最新更新