Kendo ASP.NET MVC ajudante Grid classe genérica

Eu tenho o seguinte dilema:

Eu estou tentando fazer um Kendo UI Grid dentro de uma View parcial que será usada com diferentes tipos de objetos e que podem suportar ações como Delete ou Create.

O objeto se parece com isso:

public class GridViewModel
{
    public Type ObjectType { get; set; }
    public IEnumerable<object> Items { get; set; }

    public GridViewModel(Type type, IEnumerable<object> items)
    {
        Items = items;
        ObjectType = type;
    }
}

ObjectType é uma variável do tipo Type que retém o tipo de uma classe. Por exemplo, empregado, produto, fatura ou qualquer coisa.

Itens é uma lista IEnumerable de objetos do tipo mencionado anteriormente.

Vamos dizer que temos uma visão de empregado e ligamos para o seguinte:

@model IEnumerable<Employee>
@{
    GridViewModel gridModel = new GridViewModel(typeof(Employee), Model);
}
@{
    Html.RenderPartial("_AdvancedGrid", gridModel);
}

Dessa forma, carregamos uma visão parcial com o objeto especificado como modelo.

Agora o Kendo UI Grid dentro da visão parcial:

@model XMLProject.Models.GridViewModel
@{
     System.Reflection.PropertyInfo[] propertyArray = Model.ObjectType.GetProperties();
}
@(Html.Kendo().Grid<Employee>()
    .Name("Grid")
    .Columns(columns =>
    {
        foreach (var property in propertyArray)
        {
            columns.Bound(property.Name);
        }
        columns.Command(c => c.Destroy());
    })
    .ToolBar(toolbar => toolbar.Create())
    .Groupable()
    .Pageable()
    .Sortable()
    .Scrollable()
    .Filterable()
    .Editable(editable => editable.Mode(GridEditMode.InLine))
    .DataSource(dataSource => dataSource
        .Ajax()
        .Model(model => model.Id("Id"))
        .Destroy(update => update.Action("Delete", "Products"))
        .Read(read => read.Action(ViewBag.PageLayout.ReadDataActionName, ViewBag.PageLayout.ControllerName))
        .Update(update => update.Action("Products_Update", "Home"))
        .Create(create => create.Action("Products_Create", "Home"))
        )
)

Como você pode ver, estou usando Grid <Employee>.

Mas isso é incorreto, já que eu quero usar o Grid <'any type of object'>, mas a sintaxe não me deixa dar uma string e depois alterá-la para o tipo de classe. Eu tentei coisas como:

Html.Kendo().Grid<(Type)Model.ObjectType>
Html.Kendo().Grid<typeof(Model.ObjectType)>

... e outras formas estúpidas.

Minha pergunta final é se eu posso de alguma forma enganar o compilador para ver uma string ou algo parecido como uma classe do projeto.

Eu também tentei algo como:

Html.Kendo().Grid<IProduct>

Isso funciona, mas significa que QUALQUER objeto que eu queira usar em uma grade DEVE ter todos os campos da interface do produto.

Como observação final, eu fiz este trabalho, mas sem implementar nenhuma ação Delete / Create / Update embutida na grade usando uma sintaxe diferente como:

@(Html.Kendo().Grid(Model.Items)    
    .Name("Grid")
    .Columns(columns =>
    {
        foreach (var property in propertyArray)
        {
            columns.Bound(property.Name);
        }
    })
    .Groupable()
    .Pageable()
    .Sortable()
    .Scrollable()
    .Filterable()
    .DataSource(dataSource => dataSource
        .Ajax()
        .Read(read => read.Action(ViewBag.PageLayout.ReadDataActionName, ViewBag.PageLayout.ControllerName))
    )
)

ATUALIZAR:

Eu encontrei uma solução.

@model GridViewModel
@using Kendo.Mvc.UI;

@{
    System.Reflection.PropertyInfo[] propertyArray = Model.ObjectType.GetProperties();
    List<object> mockList = new List<object>();
}

@(Html.Kendo().Grid(mockList)
    .Name("Grid")
    .Columns(columns =>
    {
        foreach (var property in propertyArray)
        {
            columns.Bound(property.Name);
        }
        columns.Command(c => c.Custom("Delete").Click("kendoGrid.onDeleteButtonClicked"));
        columns.Command(c => c.Custom("Edit").Click("kendoGrid.onEditButtonClicked"));
    })
    .Groupable()
    .Pageable()
    .Sortable()
    .Scrollable()
    .Filterable()
    .DataSource(dataSource => dataSource
        .Ajax()
        .Read(read => read.Action(Model.ReadDataActionName, ViewBag.PageLayout.ControllerName))
    )
)

O que eu fiz foi me livrar de todas as funções padrão inúteis, como Destroy ou Create, fornecidas pelo Kendo, porque elas requeriam a sintaxe com Grid <'object type'>.

O objeto GridViewModel agora se parece com isto:

public class GridViewModel
{
    public Type ObjectType { get; set; }
    public string ReadDataActionName { get; set; }

    public GridViewModel(Type type, string actionName)
    {
        ObjectType = type;
        ReadDataActionName = actionName;
    }
}

onde ReadDataActionName é o nome da ação responsável por retornar uma lista de objetos Json que a grade do Kendo pode ler.

Então eu fiz comandos personalizados que apontam para funções customizadas feitas no Jquery que envia como parâmetro um objeto bastante complexo que tem (além de todas as outras coisas) o objeto Json da grade que eu cliquei.

A coisa essencial no final é a função .Read na fonte de dados. Isso deve apontar para uma função que retorna um tipo especial de Json (vá ver a documentação do Kendo para o tipo de Json que sua ação deve retornar em seus exemplos de demonstração).

Então você não precisa de um array de objetos como você viu:

@(Html.Kendo().Grid(mockList)
    ...
)

onde mocklist é uma lista de objetos (vazia e solitária - apenas para enganar a função que não funciona de outra forma).

E o resultado FINAL é que eu tenho uma grade geral que aceita qualquer array de objetos com botões Delete e Edit que apontam para funções que podem ser customizadas com base em suas preferências - ele pode abrir um pop-up com dados de uma visão parcial, visão completa ou qualquer coisa que você quer. Eu até personalizei uma função de exclusão para fazer uma postagem de exclusão do Ajax sem qualquer confirmação requerida pelo usuário e isso funciona totalmente.

questionAnswers(0)

yourAnswerToTheQuestion