In a prior post, I blogged about creating a custom class inheriting from System.Web.Mvc.DataAnnotationsModelMetadataProvider to provide localized display names for my models.
I was disappointed to find that the MvcContrib grid doesn't use the metadata provider for column names - it just splits "Pascal-case" property names into words (e.g. "FromDate" to "From Date") if a name hasn't been explicitly assigned.
public string DisplayName
{
get
{
if (this._doNotSplit)
{
return this._displayName;
}
return this.SplitPascalCase(this._displayName);
}
}
…so I had to use the "Named" method to assign my localized column names:
Html.Grid(Model.Items)
.Attributes(@class => "mvcContribGrid jqStyleAlternateItems", border => "1")
.HeaderRowAttributes(new Dictionary<string, object> { { "valign", "bottom" } })
.RowStart(row => "<tr valign=\"top\">")
.Sort(Model.MvcContribGridSortOptions)
.Columns(column =>
{
column.For(x => x.BarCode)
.Named(LocalizedResource.BarCode)
.Action(x => Response.Write(string.Format(barCodeFormat, x.BarCode, x.Id)));
column.For(x => x.Owner)
.Named(LocalizedResource.Owner);
column.For(x => x.Description)
.Named(LocalizedResource.Description);
column.For(x => x.RetentionCode)
.Named(LocalizedResource.RetentionCode);
column.For(x => x.StatusDescription)
.Named(LocalizedResource.Status);
column.For(x => x.LegalHold)
.Named(LocalizedResource.LegalHold)
.Action(x => Response.Write((x.LegalHold) ? checkMarkCell : emptyCell));
column.For(x => x.TaxHold)
.Named(LocalizedResource.TaxHold)
.Action(x => Response.Write((x.TaxHold) ? checkMarkCell : emptyCell));
column.For(x => x.FromDate)
.Named(LocalizedResource.FromDate)
.Format(dateFormat)
.Attributes(data => dateColumnAttributes);
column.For(x => x.ToDate)
.Named(LocalizedResource.ToDate)
.Format(dateFormat)
.Attributes(data => dateColumnAttributes);
column.For(x => x.EligibleRetirementDate)
.Named(LocalizedResource.EligibleRetirementDate)
.Format(dateFormat)
.Attributes(data => dateColumnAttributes);
}).Render();
That seemed like a lot of extra work though, since I'd already gone to the trouble of creating a custom model metadata provider, so I created an extension method for ColumnBuilder<T>:
1: public static class MvcContribGridColumnExtensionMethods
2: {
3: public static IGridColumn<T> WithAutonamedColumnFor<T>(
4: this ColumnBuilder<T> @this,
5: Expression<Func<T, object>> propertySpecifier) where T : class
6: {
7: var column = (GridColumn<T>) @this.For(propertySpecifier);
8:
9: ModelMetadata metadata = ModelMetadataProviders.Current
10: .GetMetadataForProperty(() => null, typeof(T), column.Name);
11:
12: return column.Named(metadata.DisplayName);
13: }
14: }
Line 7 uses the ColumnBuilder object's standard "For" method to initialize the column.
Line 9 gets the current model metadata provider for the model class and the current property (which for my site is my custom provider).
Line 12 returns the IGridColumn<T> object with the DisplayName assigned by the model metadata provider.
Now in my view I can get rid of the ".Named" calls and just use my ".WithAutomatedColumnFor" extension instead of the standard ".For" and ".Named" methods to initialize each column:
Html.Grid(Model.Items)
.Attributes(@class => "mvcContribGrid jqStyleAlternateItems", border => "1")
.HeaderRowAttributes(new Dictionary<string, object> { { "valign", "bottom" } })
.RowStart(row => "<tr valign=\"top\">")
.Sort(Model.MvcContribGridSortOptions)
.Columns(column =>
{
column.WithAutonamedColumnFor(x => x.BarCode)
.Action(x => Response.Write(string.Format(barCodeLinkFormat, x.BarCode, x.Id)));
column.WithAutonamedColumnFor(x => x.Owner);
column.WithAutonamedColumnFor(x => x.Description);
column.WithAutonamedColumnFor(x => x.RetentionCode);
column.WithAutonamedColumnFor(x => x.StatusDescription);
column.WithAutonamedColumnFor(x => x.LegalHold)
.Action(x => Response.Write((x.LegalHold) ? checkMarkCell : emptyCell));
column.WithAutonamedColumnFor(x => x.TaxHold)
.Action(x => Response.Write((x.TaxHold) ? checkMarkCell : emptyCell));
column.WithAutonamedColumnFor(x => x.FromDate)
.Format(dateFormat)
.Attributes(data => dateColumnAttributes);
column.WithAutonamedColumnFor(x => x.ToDate)
.Format(dateFormat)
.Attributes(data => dateColumnAttributes);
column.WithAutonamedColumnFor(x => x.EligibleRetirementDate)
.Format(dateFormat)
.Attributes(data => dateColumnAttributes);
}).Render();