JoeyD
JoeyD

Reputation: 743

Generic Kendo MVC Grid Used with Different Models

I am trying to use a Kendo Grid generically as a partial view. Kendo requires either a type defined or a datatable to instantiate the grid in a razor view

@(Html.Kendo().Grid<object>() or @(Html.Kendo().Grid(dataTable)

My issue is i want to use the Grid for whatever object, not a specific one.

@(Html.Kendo().Grid<object>()
    .Name(Model.MetricName)
    .Resizable(resizing => resizing.Columns(true))
    .Reorderable(reorder => reorder.Columns(true))
    .Sortable(sorting => sorting.Enabled(true))
    .Pageable(pager => pager.PageSizes(new int[] { 10, 15, 20, 50 }))
    .ColumnMenu()
    .DataSource(dataSource => dataSource
            .Ajax()
            .Read(read => read.Action(Model.MetricName, "AdHocReport", new { metricId = Model.MetricId }))
    )

)

by using Object i am able to dynamically load the data returned from the ajax .read method. However the issue is with dates. They are returned in JSON format.

Ive tried this method and I still get JSON string representation of the date

Kendo ASP.NET MVC helper Grid generic class

Is there a way to define the type of grid from a string representation of the type? So lets say i have a string property on the viewModel that is the type of the grid. How can i say Grid ?

ive tried using reflection to instantiate the type but i get the infamous "you are using a variable like a type"

This is driving me nuts... any and all help would be greatly appreciated

Upvotes: 1

Views: 1400

Answers (1)

JoeyD
JoeyD

Reputation: 743

So i found the way to make this work and bind correctly and as mentioned above my mrmashal it has to do with using dataTables.

@(Html.Kendo().Grid(Model.GridTable)

here is the viewModel property

public DataTable GridTable { get; set; }

To make this dynamic i use reflection to define the dataTable based upon the properties of a the class i want to populate the grid with

Type elementType = Type.GetType(className, true);
var properties = elementType.GetProperties();

DataTable dataTable = new DataTable();
foreach (PropertyInfo info in properties)
    {
        dataTable.Columns.Add(new DataColumn(info.Name, Nullable.GetUnderlyingType(info.PropertyType) ?? info.PropertyType));
    }
viewModel.GridTable = dataTable;

However, the key is making sure that the data returned from the AJAX read was a dataTable, not an IEnumerable type.

DataTable dataTable = ToDataTable<AssetLocationHistoryMetricData>(metricData);

var result = dataTable.ToDataSourceResult(request);

and this is what i used to convert the List to a dataTable

public static DataTable ToDataTable<T>(IEnumerable<T> items)
    {
        DataTable dataTable = new DataTable(typeof(T).Name);

        //Get all the properties
        PropertyInfo[] Props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
        foreach (PropertyInfo prop in Props)
        {
            //Setting column names as Property names
            dataTable.Columns.Add(prop.Name);
        }
        foreach (T item in items)
        {
            var values = new object[Props.Length];
            for (int i = 0; i < Props.Length; i++)
            {
                //inserting property values to datatable rows
                values[i] = Props[i].GetValue(item, null);
            }
            dataTable.Rows.Add(values);
        }
        //put a breakpoint here and check datatable
        return dataTable;
    }

Upvotes: 2

Related Questions