【问题标题】:are dynamic columns possible with MVC.Grid?MVC.Grid 可以使用动态列吗?
【发布时间】:2020-12-31 17:37:31
【问题描述】:

我正在为 MVC5 应用程序构建一个用于查找表管理的接口。每个查找都封装在自己的模型中。希望/想法是我可以动态地将我选择的任何模型输入到包含MVC.Grid 的单个 Razor 页面中。不幸的是,MVC.Grid 的语法要求我对给定模型的属性进行硬编码。

有没有办法为给定模型的每个属性动态添加一列?

@model IQueryable<Person>

@(Html
    .Grid(Model)
    .Build(columns =>
    {
        columns.Add(model => model.Name).Titled("Name");
        columns.Add(model => model.Surname).Titled("Surname");
        columns.Add(model => model.MaritalStatus).Titled("Marital status");
    })
)

【问题讨论】:

    标签: c# asp.net-mvc razor


    【解决方案1】:

    要简单地在视图中显示所有列的网格,您只需在视图中使用声明的 WebGrid 中的 GetHTML

    @model IQueryable <Person>
    @{
        WebGrid grid = new WebGrid(Model);
    }
    
    <div>@grid.GetHtml()</div>
    

    编辑: 有更多选项

    @model IQueryable <Person>
    @{
        WebGrid grid = new WebGrid(Model, rowsPerPage: 10, canSort: true);
    }
    
    <div>
    @grid.GetHtml(
    tableStyle : "table table-responsive table-striped table-bordered", 
    htmlAttributes: new
        {
            id = "grid1"
        })
    </div>
    

    如您所见,您可以在 C# 代码中自定义网格行为以进行排序、限制行数...等。 并且还通过对网格应用一些样式来对您的 HTML 进行样式设置,提供一个 Id,...等等。

    您可以查看这两个链接以了解更多信息,因为有很多选项无法在单个帖子中显示。

    Microsoft WebGrid.GetHtml Method

    MVC Webgrid basics – Simple grid with paging and sorting and selection

    【讨论】:

    • 感谢您的回答演示了一种无需对每列进行硬编码即可显示网格的方法。但是,您的示例无法控制标题文本。更重要的是,我选择使用 MVC.Grid 是因为它具有一系列内置功能:过滤(按列)、搜索(整个网格)、导出(到 Excel)等。失去所有这些功能只是为了动态显示模型产生的问题多于它解决的问题。
    • 我只是想让它尽可能简单,以便您了解如何实现它,让我为您编辑一些细节;)
    • 嗯...在“简化”这一点时,您有点错过了重点。这真的不是关于网格的首选选择的问题。它是关于动态循环属性的。即使我选择了 WebGrid 并且 放弃了导出支持并且 花了几个小时在不易获得的特定类型过滤器中进行编程......标题。如果不指定每一列(就像我已经在 MVC.Grid 中所做的那样),我不会得到格式化的标题,因此我仍然会寻找一种方法来动态循环遍历属性。
    【解决方案2】:

    MVC.Grid 页面上的一个示例是使用数据表完成的,如果可能的话,您可以使用它。

    除此之外,它归结为创建一个以某种方式访问​​数据的表达式。您可以使用以列名作为键的自己的数据结构,可以使用 .NET 表达式生成器等创建动态表达式。

    @(Html
        .Grid(Model.Rows)
        .Build(columns =>
        {
            foreach (var column in Model.DynamicColumns)
            {
                columns.Add(model => model.GetValueFor(column.Name)).Titled(column.Label);
            }
            // or
            foreach (var column in Model.DynamicColumns)
            {
                columns.Add(column.BuildDataAccessExpression()).Titled(column.Label);
            }
        })
    )
    
    

    如果.Add(...) 方法不支持你的表达式,你可以使用限制较少的函数api 来代替.Add().RenderedAs(...)

    【讨论】:

    • 感谢您的回答演示了一种动态添加列的方法。然而,它回避了我这样做的愿望for each property of a given Modelcolumn.Label 不会从模型中检索显示名称。 .BuildDataAccessExpression() 似乎也不是合法代码。确认这个概念很好,但我希望的不仅仅是构建伪代码。 My update 是朝着正确方向迈出的更近一步...除了 MVC.Grid 沿途中断。
    • ...说了这么多:我的输出自然不适合 C# DataTable 类...但是 大多数 的设置因列而异your example 是字符串。调查。但是,每一列都被硬编码为 String 类型。可以用变量字符串设置类型吗? (如果不是:再一次,我的动态尝试因硬编码的需要而受阻。)
    • 我刚刚展示了一个概念。我不知道您想通过GetType().GetProperties() API 显式构建您的列。必须在列级别启用过滤和排序,因为网格会自动将其禁用用于复杂的表达式,因为它们仅适用于内存数据。如果您希望排序和过滤与数据库提供程序一起使用,您仍然需要构建表达式。
    【解决方案3】:

    这里有一些更符合我预期的东西。

    对于给定的模型...

    public class Person
    {
        [Display(Name = "Name")]
        public string Name { get; set; }
    
        [Display(Name = "Marital Status")]
        public string MaritalStatus { get; set; }
    
        [Display(Name = "Years Married")]
        public int Years { get; set; }
    }
    

    我可以几乎像这样为模型的每个属性动态添加一列:

    @model IQueryable<Person>
    
    @(Html
        .Grid(Model)
        .Build(columns =>
        {
            foreach (var column in typeof(Person).GetProperties())
            {
                var type = typeof(Person);
                var memInfo = type.GetMember(column.Name);
                var attributes = memInfo[0].GetCustomAttributes(typeof(System.ComponentModel.DataAnnotations.DisplayAttribute), false);
                var displayname = ((System.ComponentModel.DataAnnotations.DisplayAttribute)attributes[0]).Name;
    
                columns.Add(m => m.GetType().GetProperty(column.Name).GetValue(m)).Titled(displayname);
            }
        })
        .Filterable()
        .Sortable()
    )
    

    但是...过滤和排序已经消失,现在我不再对列进行硬编码。通过 JavaScript 添加事件监听器现在也失败了。模型属性的动态解析破坏了某些东西……强类型,也许?

    在这个方向上有什么进一步的见解,有人吗?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-06-15
      • 2020-06-11
      • 1970-01-01
      • 2010-09-05
      • 2021-09-15
      • 1970-01-01
      • 2013-10-30
      相关资源
      最近更新 更多