My Technical Notes

Wednesday, 16 June 2010

MVC Html Grid Sorting by Composite Column

Sometimes when using MvcContrib's Grid feature you may end up with columns which are a composite of two or more properties or you might have formatting in the expression. For example, you may have the following:

  column.For(x => x.Name + ": " + x.Description);
For such expressions, although the content generated is correct, it does not include a "Column" parameter on the column header link to sort the column. For the above example, we would naturally want to sort by the Name rather than the Description. It would be useful to have an extension method on IGridColumn which could be called as follows:

  column.For(x => x.Name + ": " + x.Description).SortableAs(x => x.Name);
The above extension method was quite easy to write but since the author has made the GridColumn.Name property with only a get accessor and no set, I had to use reflection in order to retrieve the underlying field and then set it:

public static class GridExtensions
{
    public static IGridColumn<TModel> SortableAs<TModel, TProperty>(this IGridColumn<TModel> column, Expression<Func<TModel, TProperty>> propertySpecifier) where TModel: class
    {
        var propertyName = ExpressionHelper.GetExpressionText(propertySpecifier);
        return column.SortableAs(propertyName);
    }

    public static IGridColumn<TModel> SortableAs<TModel>(this IGridColumn<TModel> column, string propertyName) where TModel : class
    {
        var _nameField = typeof(GridColumn<TModel>).GetField("_name", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
        _nameField.SetValue(column, propertyName);
        return column;
    }
}

No comments: