【问题标题】:Get the DisplayName of a property on an arbitrary type获取任意类型的属性的 DisplayName
【发布时间】:2013-01-28 20:49:59
【问题描述】:

我很难找到一种干净的方法来做到这一点。我有一个 ViewModel 类,其中包含一个表的行集合。我希望能够在 strongly-typed 集合中的类型上执行 @Html.DisplayNameFor() 而无需引用集合中的第一项或创建该类型的新实例。所以为了澄清这里是一个例子:

public class TableViewModel
{
  public string Title { get; set; }
  public IEnumerable<Row> Rows { get; set; }
}

public class Row
{
  public int ColumnA { get; set; }
  public int ColumnB { get; set; }
}

//In the Razor view
<table>
  <tr>
    <th>@Html.DisplayNameFor(???)</th>
  </tr>
</table>

有没有办法在不使用@Html.DisplayNameFor(x =&gt; x.Rows.First().ColumnA) 的情况下做到这一点?

【问题讨论】:

  • 这是你想要做的吗? stackoverflow.com/questions/3885796/…
  • 您可以将public Row Row { get; set; } 添加到您的视图模型中。
  • @LeviBotelho - 我在研究中看到了这个问题,但它并不完全符合要求,因为它不涉及收藏。
  • @Forty-Two - 我想我所设想的是一个辅助方法解决方案。我并不热衷于向我的虚拟机添加额外的属性。

标签: c# asp.net-mvc


【解决方案1】:

您可以使用this.ViewData.ModelMetadata.Properties 集合并调用GetDisplayName 方法来生成标题单元格内容。我们通常在代码中执行此操作,以将任意模型呈现为表格。

编辑: 为了对此进行扩展,我使用了一个基本模型,它表示一个表并且只表示一个表。我定义了 3 个类。我有一个TableRowCell' class, aTableRow' 类(本质上是TableRowCell 对象的集合)和一个Table 类。

public class Table
{
    public Table(String name)
    {
        this.Name = name;
        this.ContentRows = new List<TableRow>();
        this.HeaderRow = new TableRow();
        this.FooterRow = new TableRow();
    } 

    public IList<TableRow> ContentRows
    {
        get;
        private set;
    }

    public TableRow FooterRow
    {
        get;
        private set;
    }

    public TableRow HeaderRow
    {
        get;
        private set;
    }

    public String Name
    {
        get;
        private set;
    }
}

当我的视图模型包含我想在表格中显示的对象集合时,我首先调用HtmlHelper 扩展,该扩展将该集合转换为Table 对象。在该方法中,我遍历了对ModelMetadataProviders.Current.GetMetadataForType(null, typeof(TModel)).Properties..Where(item =&gt; item.ShowForDisplay) 的调用,以获取用于生成标题单元格的元数据对象的集合。然后我遍历项目集合并调用ModelMetadataProviders.Current.GetMetadataForType(() =&gt; item, typeof(TModel)).Properties..Where(item =&gt; item.ShowForDisplay) 以获取用于生成内容单元格的元数据对象集合。

从技术上讲,我的HtmlHelper 扩展方法实际上返回了一个TableBuilder 对象,该对象将有一个名为Render 的方法来生成html。到目前为止,这种设置对我很有帮助。

【讨论】:

  • 您将如何为 IEnumerable 中的类型泛型类型执行此操作? IEnumerable 的 I.E,如何获取 Row 的元数据?
  • 我在回答中详细阐述了一点,试图解决您的问题。
  • 太好了,ModelMetadataProvers.Current.GetMetadataForType 方法正是我想要的。感谢您分享您的解决方案。
【解决方案2】:
public class TableViewModel
{
  public string Title { get; set; }
  public IEnumerable<Row> Rows { get; set; }
  public Row ForNames = null;
}


@Html.DisplayNameFor(x => x.ForName.ColumnA)

【讨论】:

    猜你喜欢
    • 2023-03-30
    • 1970-01-01
    • 2015-04-12
    • 2012-12-05
    • 1970-01-01
    • 2021-09-12
    • 1970-01-01
    • 2019-09-28
    • 2019-07-11
    相关资源
    最近更新 更多