I'm writing a custom HTML helper to display a Grid and I'm focussing myself on Telerik and other parties for the syntax I would like to use.
I have a model with 3 properties (Name, DateUpdated and DateCreted) and an IEnumerable of that one is passed to my view:
@model IEnumerable<GridPageFolderViewModel>
Then I have my static HtmlHelperExtensions class:
public static class HtmlHelperExtensions
{
#region Grid
public static GridBuilder<TModelEntry> GridFor<TModel, TModelEntry>(this HtmlHelper<TModel> htmlHelper, TModelEntry model)
{
return new GridBuilder<TModelEntry>();
}
#endregion
}
This class does return a GridBuilder which looks as the following:
public class GridBuilder<TModel> : IGridBuilder
{
#region Properties
private string name { get; set; }
#endregion
#region Methods
public GridBuilder<TModel> WithColumns(Action<ColumnBuilder<TModel>> function)
{
return this;
}
internal MvcHtmlString Render()
{
return new MvcHtmlString("This is a value.");
}
#endregion
#region IGridBuilder Members
public GridBuilder<TModel> Name(string name)
{
this.name = name;
return this;
}
#endregion
#region IHtmlString Members
public string ToHtmlString()
{ return Render().ToHtmlString(); }
#endregion
}
And then I have my ColumnBuilder class.
public class ColumnBuilder<TModel>
{
public void Bind<TItem>(Func<TModel, TItem> func)
{
}
}
With all this code into place (nothing is rendered at this point), I can use the following syntax:
@(Html.GridFor(new GridPageFolderViewModel())
.Name("PageOverviewGrid")
.WithColumns(column =>
{
column.Bind(c => c.Name);
column.Bind(c => c.DateCreated);
column.Bind(c => c.DateUpdated);
}
)
The 'problem' here is that I need to specify the type of object that a single item in the Grid is holding (the GridPageFolderViewModel), otherwise, I cannot access the properties in the column binder code.
Anyone has some advice on how I can get rid of it?
As the view model is IEnumerable<GridPageFolderViewModel>
, you just need to declare your helper like this:
public static GridBuilder<TModelEntry> GridFor<TModelEntry>(this HtmlHelper<IEnumerable<TModelEntry>> htmlHelper)
{
return new GridBuilder<TModelEntry>();
}
It would mean your helper can only be used on views where the model is an IEnumerable<T>
, but I think that makes sense.
Now in your view you can do:
@(Html.GridFor()
.Name("PageOverviewGrid")
.WithColumns(column =>
{
column.Bind(c => c.Name);
column.Bind(c => c.DateCreated);
column.Bind(c => c.DateUpdated);
}
)
PS. Don't worry if you need to access the model inside your helper. You can still retrieve it from htmlHelper.ViewData.Model
, which will be nicely typed as IEnumerable<TModelEntry>
Hope it helps!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With