Question

I'm using MVC's WebGrid throughout my application and it's been working great. I'm setting the columns for the grid in my controller code and then passing that to my view. I add a new column like this where columns is a List<MvcWebGridColumn>:

columns.Add(new WebGridColumn { ColumnName = "Path", Header = "Full Path", Filter = ... });

And then in my view, I set the grid columns from my view model like this:

@grid.GetHtml(
    footerStyle: "hide",
    mode: WebGridPagerModes.All,
    htmlAttributes: new { id = @Model.Id },
    columns: @Model.Columns)

Up until this point, setting the columns in the code has worked great as the columns have been known, first-level properties of my models. Now things are more complicated and I don't know how to handle it with the WebGrid. Here is an example model:

public class Requirement
{
    public string Id { get; set; }
    public string Path { get; set; }
    public Dictionary<string, string> Fields { get; set; }
}

I want to be able to set a WebGrid's column in the code using the value from the Field dictionary property's key. I'm trying this, but it's not working:

columns.Add(new WebGridColumn { ColumnName = String.Format("Fields[\"{0}\"]", key), Header = label });

I tried also putting a method GetFieldValue(string key) method on my Requirement model, but it doesn't like that either. It seems like it can only handle exactly matching an object's property identifier.

I'm not sure if this is possible using WebGrid out of the box or if I have to extend the functionality. Thanks in advance.

Was it helpful?

Solution

I believe I just came up with a way to handle this that doesn't seem too hacky.

To restate the problem, I believe the MVC WebGrid uses reflection to set the ColumnName property so the string you enter for that needs to be directly accessible via the object's API eg. "Id", "Field.Address.Name", etc. The problem in my case is that the value I need for my column's row comes from a Dictionary and it doesn't seem like you can pass a parameter (key, index, etc) into the ColumnName to get the value I need.

My solution is to avoid using the ColumnName property of the WebGrid entirely when resolving the value to be displayed. I simply enter a value for the grid's model that I know exists for the ColumnName, in my case "Id". This is just used so the WebGrid will render. Then, since the Format of the WebGridColumn uses a dynamic function, I can define my column value using whatever I want:

columns.Add(new WebGridColumn
{
    ColumnName = "Id",
    Header = field.Label,
    Format = x => new HtmlString(x.Value.GetEntityFieldValue(field.Field))
});

I soon realized that this will mess up sorting. MVC WebGrid's black-box sort simply uses the ColumnName in the sort query so every column for me now has "?sort=Id". If you're not sorting, then you're OK. If you are, you'll have to implement a custom sorting solution like I'm currently doing.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top