When creating a WebGridColumn, it requires passing in a string for the columnName that will be used. Why doesn't it allow passing a lambda expression like most other HTML Helpers? How can I pass a simple lambda to gain intellisense hints, preserve type-safety, and prevent runtime errors due to typos? And with the column name, shouldn't WebGrid be able to use the metadata display attributes to set the header and format by default?
What we use on a regular basis:
@{ 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))
)
)
This was the question posed to me by a colleague. We use WebGrid extensively, and having to repeatedly type the same info in duplicate or triplicate for every column was... frustrating to say the least. I looked into extending
WebGriditself, but that seemed like it would take a loooot of work to make generic and type-safe. Instead, I wrote anHtmlHelperextension that returns aWebGridColumn.Code
Anywhere you would normally use
WebGrid.Column()instead useHtml.GridColumnFor().That is beautiful...
What's going on?
It uses built-in Expression functionality to get the full property name to pass to the WebGridColumn constructor, and gets the already built-in metadata from MVC to get the name to display for headers, and check for formatting.
It also accepts overrides for the header and format values, so you can set them yourself; you may want one Person object for multiple pages, but some to call the
Birthdatefield "Birthday", and maybe others to call it "Date of Birth" (we try to avoid that, but sometimes it's an end user requirement), or show only the day and month: