I'm building a custom HTML helper with an expression to draw a tag cloud where the data that goes into the tag cloud comes from the expression. I'll let the code do the talking here:
View Model
public class ViewModel
{
public IList<MyType> MyTypes { get; set; }
public IList<MyOtherType> MyOtherTypes { get; set; }
}
View
<div>
@Html.TagCloudFor(m => m.MyTypes)
</div>
<div>
@Html.TagCloudFor(m => m.MyOtherTypes)
</div>
Helper
public static MvcHtmlString TagCloudFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression) where TProperty : IList<MyType> where TProperty : IList<MyOtherType>
{
// So my actual question here is: how do I get my IList<TProperty> collection
// so I can iterate through and build my HTML control
}
I've had a quick look around and have done the usual Google searches, but I can't quite seem to find that specific answer. I assume it's somewhere in the region of expression.Compile().Invoke()
but I'm not sure what the correct parameters to pass are.
I should also mention that MyType
and MyOtherType
have a similar property of Id
but there's no inheritance here, they are completely separate objects hence I'm constraining my TProperty
as IList<MyType>
and IList<MyOtherType>
. Am I heading down the wrong path here, I feel like this should be obvious, but my brain isn't playing.
The following should do it:
public static MvcHtmlString TagCloudFor<TModel , TProperty>( this HtmlHelper<TModel> helper , Expression<Func<TModel , TProperty>> expression )
where TProperty : IList<MyType>, IList<MyOtherType> {
//grab model from view
TModel model = (TModel)helper.ViewContext.ViewData.ModelMetadata.Model;
//invoke model property via expression
TProperty collection = expression.Compile().Invoke(model);
//iterate through collection after casting as IEnumerable to remove ambiguousity
foreach( var item in (System.Collections.IEnumerable)collection ) {
//do whatever you want
}
}
How about....
public static MvcHtmlString TagCloudFor<TModel , TItemType>( this HtmlHelper<TModel> helper , Expression<Func<TModel , IEnumerable<TItemType>>> expression )
// optional --- Where TItemType : MyCommonInterface
{
TModel model = (TModel)helper.ViewContext.ViewData.ModelMetadata.Model;
//invoke model property via expression
IEnumerable<TItemType> collection = expression.Compile().Invoke(model);
foreach( var item in collection ) {
//do whatever you want
}
}
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