2014-04-14 47 views
2

我想为ASP.NET和Razor创建一种WebGrid 2.0。PropertyInfo to Expression <Func <TModel,TProperty >>

定义ModelClass(TData)时,WebGrid应自行为表创建HTML。

TData的属性应该通过反射(typeof(TData).GetProperties)读取。属性的属性应该定义一些css和html样式或甚至一些数据(DisplayNameAttribute => ColumnHeader)。

现在我来到了这一点,当我想调用htmlHelper.DisplayFor(... propertyInfoToExpression ...)来呈现数据内容。

我怎么能调用DisplayFor,当我只有数据(行)/模型和propertyInfo?


的WebGrid级:

public class TableModel<TData>{ 

    private readonly IList<TData> _rows; 
    private readonly IList<TableColumn<TData>> _columns = new List<TableColumn<TData>>(); 


    public TableModel(IList<TData> rows) { 
     _rows = rows; 

     PropertyInfo[] propertyInfos = typeof(TData).GetProperties(); 
     foreach (PropertyInfo property in propertyInfos) { 
      if (!Attribute.IsDefined(property, typeof(NoColumnAttribute))) { 
       _columns.Add(new TableColumn<TData>(property)); 
      } 
     } 

    } 

    private MvcHtmlString GetCellHtml(HtmlHelper<TData> helper, TableColumn column, TData dataRow){ 

     TagBuilder cellTagBuilder = new TagBuilder("td"); 
     cellTagBuilder.InnerHtml = helper.DisplayFor(...propertyInfoToExpression...) 

    } 

    public MvcHtmlString ToHtml(HtmlHelper helper){ 
     TagBuilder tableTagBuilder = new TagBuilder("table"); 
     TagBuilder headTagBuilder = new TagBuilder("thead"); 
     TagBuilder bodyTagBuilder = new TagBuilder("tbody"); 

     ... 
     return new MvcHtmlString(tableTagBuilder); 
    } 
} 

样品班TDATA正好赶上这个想法:

public class UserModel{ 

     [NoColumnAttribute] 
     public int Id{get;set;} 

     [CssClass("name")] 
     public string Firstname {get;set;} 

     [CssClass("name")] 
     public string Lastname{get;set;} 

     [CssClass("mail")] 
     public string Mail{get;set;} 

     [CssClass("phone")] 
     public string Phone{get;set;} 

} 
+0

什么?你能用样本代码来描述它吗(对于模式,以及所需呼叫结构的片段)。可能很容易找出解决方案。通常用表达式可以解决事情,而无需处理PropertyInfo。 – Dbl

+0

我添加了一些示例代码。 – Tobias

+0

我不认为你的班级概念是正确的吗?我想你想这样调用它(假设你传递给你的视图的模型是UserModel类型的:@ Html.WebGridFor(x => x)?制作它的列表将是毫无意义的 我想你'重新修改你的代码 – Dbl

回答

1

你试过......

private MvcHtmlString GetCellHtml(HtmlHelper<TData> helper, TableColumn column, TData dataRow){ 

    TagBuilder cellTagBuilder = new TagBuilder("td"); 
    cellTagBuilder.InnerHtml = helper.Display(column.PropertyInfo.Name, dataRow); 
    ... 
} 

.. 。?

如果您需要DisplayFor仅适用于您的方法GetCellHtml那么您并不需要从PropertyInfo构建表达式。

+0

老实说:我并没有真正了解显示方法,但我会试一试。 – Tobias

+0

我试过了,并得到它的工作。不需要dataRow,因为助手定义了模型中的数据,显示的参数是附加的视图信息。 最终解决方案: public MvcHtmlString GetHtml(HtmlHelper 帮手){ return helper.Display(PropertyInfo.Name); } – Tobias

1

你可以尝试这样的:

 var properties = typeof (TModel).GetProperties(); 
     foreach (PropertyInfo info in properties) 
     { 
      ParameterExpression p1 = Expression.Parameter(typeof(TModel), "m"); 
      ParameterExpression p2 = Expression.Parameter(info.PropertyType, "m."+info.Name); 
      Expression<Func<TModel, dynamic>> exResult = Expression.Lambda<Func<TModel, dynamic>>(p1, p2); 

      helper.DisplayFor(exResult); 
     } 

遗憾的是过了好一会儿。必须做一些其他的工作。

+0

我不得不改变p1和p2的顺序来使表达式工作。不幸的是,displayfor methode显示所有属性,而不仅仅是表达式定义的属性。不过,我给了你一个赞成票。 – Tobias

+0

好吧。无论如何,很高兴你能够正常工作。如果你仍然在使用反射,尽管你应该看看编译后的表达性能与reflection + GetValue。性能差异很大。所以对于这个问题,使用表达式可能会在以后帮助你。 – Dbl

相关问题