我想为ASP.NET和Razor创建一种WebGrid 2.0。
定义一个ModelClass(TData),WebGrid应该自己为表创建HTML。
TData的属性应该通过反射读取(typeof(TData).GetProperties)。属性的属性应该定义一些css和html样式,甚至一些数据(DisplayNameAttribute=>ColumnHeader)。
现在我说到点子上了,当我想调用htmlHelper.DisplayFor(…propertyInfoToExpression…)来呈现数据内容时。
当我只得到数据(行)/模型和属性信息时,我如何调用DisplayFor?
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;}
}
您可以这样尝试:
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);
}
很抱歉花了一段时间。不得不做一些其他的工作。
你试过。。。
private MvcHtmlString GetCellHtml(HtmlHelper<TData> helper, TableColumn column, TData dataRow){
TagBuilder cellTagBuilder = new TagBuilder("td");
cellTagBuilder.InnerHtml = helper.Display(column.PropertyInfo.Name, dataRow);
...
}
如果方法GetCellHtml
只需要DisplayFor
,那么实际上不需要从PropertyInfo构建表达式。