创建WebGridColumn时,它需要为要使用的columnName传入一个字符串。它为什么不允许像大多数其他HTML Helper一样传递lambda表达式?如何传递一个简单的lambda以获得智能提示,保留类型安全性并防止由于错字引起的运行时错误?并且使用列名,WebGrid是否不应该默认使用元数据显示属性来设置标题和格式?
我们定期使用的内容:
@{ var grid = new WebGrid(model) }
@grid.GetHtml(
// table style formats here...
columns: grid.Columns(
grid.Column(columnName: "StudentName",
header: Html.DisplayNameFor(model => model.StudentName)),
grid.Column(columnName: "Birthdate",
header: Html.DisplayNameFor(model => model.Birthdate),
format: (item) => Html.DisplayFor(modelItem => (item as WebGridRow).Value as Person).Birthdate),
grid.Column(columnName: "Address.Physical.StreetNumber",
header: Html.DisplayFor(model => model.Address.Physical.StreetNumber)),
grid.Column(columnName: "Address.Physical.StreetName",
header: Html.DisplayFor(model => model.Address.Physical.StreetName))
)
)
这是一个同事向我提出的问题。我们广泛使用WebGrid,并且不得不为每一列重复输入相同的信息(一式三份或一式三份),这至少令人沮丧。我研究了扩展WebGrid
本身,但是似乎要花很多时间才能使泛型和类型安全。相反,我写了一个HtmlHelper
扩展名,返回了WebGridColumn
。
public static WebGridColumn GridColumnFor<TModel, TValue>(this HtmlHelper<IEnumerable<TModel>> html, Expression<Func<TModel, TValue>> exp, string header = null, Func<dynamic, object> format = null, string style = null, bool canSort = true)
{
var metadata = ModelMetadata.FromLambdaExpression(exp, new ViewDataDictionary<TModel>());
var modelText = ExpressionHelper.GetExpressionText(exp);
if (format == null && metadata.DisplayFormatString != null)
{
format = (item) => string.Format(metadata.DisplayFormatString, item[modelText] ?? String.Empty);
}
return new WebGridColumn()
{
ColumnName = modelText,
Header = header ?? metadata.DisplayName ?? metadata.PropertyName ?? modelText.Split('.').Last(),
Style = style,
CanSort = canSort,
Format = format
};
}
通常在任何地方都使用WebGrid.Column()
代替使用Html.GridColumnFor()
。
columns: grid.Columns(
Html.GridColumnFor(model => model.Name),
Html.GridColumnFor(model => model.Birthdate),
Html.GridColumnFor(model => model.Address.Physical.StreetNumber),
Html.GridColumnFor(model => model.Address.Physical.StreetName),
)
那真漂亮...
[它使用内置的Expression功能获取完整的属性名称,以传递给WebGridColumn构造函数,并从MVC获取已内置的元数据,以获取要显示的标题名称,并检查格式。
它还接受标题和格式值的替代,因此您可以自己设置它们;您可能希望一个Person对象用于多个页面,但有些人将Birthdate
字段称为“生日”,而另一些人将其称为“出生日期”(我们尽量避免这种情况,但有时这是最终用户的要求),或仅显示日期和月份:
Html.GridColumnFor(model => model.Birthdate, format: (item) => item.Birthdate.ToString("MM/dd"))