mrfazolka
mrfazolka

Reputation: 790

C# reflection, lambda?

I need to do this using reflection:

@Html.Grid((IEnumerable<MyType>)list).Columns(columns =>
           {
                 columns.Add(foo => foo.Title)
                        .Titled("Custom column title")
                        .SetWidth(110);
                 columns.Add(foo => foo.Description)
                        .Sortable(true);
           }).WithPaging(20)

Now I have var g which is object created after call @Html.Grid((IEnumerable<Type>)Model) using reflection. This is done by reflection because list contains object of class created at runtime and I need to call Grid(list) with defined type(which didn't exist at compile time):

var method = typeof(GridMvc.Html.GridExtensions).GetMethods()
                        .Where(mi => mi.Name == "Grid")
                        .ElementAt(0)
                        .MakeGenericMethod(new Type[] { t });
var g = method.Invoke(null, new object[] { Html, list });

So I need do something like:

g.Columns(columns =>
               {
                     columns.Add(foo => foo.Title)
                            .Titled("Custom column title")
                            .SetWidth(110);
                     columns.Add(foo => foo.Description)
                            .Sortable(true);
               }).WithPaging(20)

using reflection.

var g is type of HtmlGrid:

https://github.com/leniel/Grid.Mvc/blob/master/GridMvc/Html/HtmlGrid.cs

Can someone provide example code to do this?


To be on the safe side I am adding Grid.Mvc github link: https://github.com/leniel/Grid.Mvc/blob/master/GridMvc/ because I don't know the way to solve it

Upvotes: 1

Views: 318

Answers (1)

xanatos
xanatos

Reputation: 111860

Third time is the charm :)

This time I tested it.

You use it like

@Html.MakeGrid(items, someType)

where someType is the Type of your objects.

or even

this.Write(Helper.MakeGrid(Html, items, someType);

or in any way you would use your @Html.Grid method.

I cheat twice: once I call through reflection from the non-generic MakeGrid a generic MakeGridInternal, and the second time in CreateColumns where I use reflection to get the PropertyInfo of the various columns.

Note that when calling MakeGrid you must pass the real type of your elements in type, and items must be a collection of any reference type (but 90% it will work if you change the signature to object items)

public static class Helper {
    public static IHtmlString MakeGrid(this HtmlHelper html, IEnumerable<object> items, Type type) {
        // You can give even this signature:
        // public static IHtmlString MakeGrid(HtmlHelper html, object items, Type type)
        // But clearly items MUST be a collection of some type!
        return (IHtmlString)typeof(Helper).GetMethod("MakeGridInternal").MakeGenericMethod(type).Invoke(null, new object[] { html, items });
    }

    public static IHtmlString MakeGridInternal<T>(HtmlHelper html, IEnumerable<T> items) where T : class {
        return GridMvc.Html.GridExtensions.Grid<T>(html, items)
                 .Columns(CreateColumns)
                 .WithPaging(10);
    }

    public static void CreateColumns<T>(IGridColumnCollection<T> columns) {
        Type t = typeof(T);

        PropertyInfo title = t.GetProperty("Title");
        PropertyInfo description = t.GetProperty("Description");

        columns.Add(title)
            .Titled("MyTitle")
            .SetWidth(100);

        columns.Add(description)
            .Sortable(true);
    }
}

Upvotes: 1

Related Questions