Kendo ASP.NET MVC帮助器网格通用类

Pri*_*lin 5 c# asp.net-mvc-4 kendo-grid kendo-asp.net-mvc

我有以下困境:

我正在尝试在局部视图内制作Kendo UI网格,该视图将与不同类型的对象一起使用,并且可以支持诸如Delete或Create之类的操作。

该对象如下所示:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

ObjectType是类型类型的变量,该变量保留类的类型。例如员工,产品,发票或其他任何东西。

Items是前面提到的类型的IEnumerable对象列表。

假设我们有一个Employee View,我们在以下内部调用:

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

这样,我们以指定对象作为模型加载局部视图。

现在,Kendo UI Grid在局部视图内:

@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"))
        )
)
Run Code Online (Sandbox Code Playgroud)

如您所见,我正在使用Grid <Employee>。

但这是不正确的,因为我想使用Grid <'any type of object'>,但是语法不允许我给它一个字符串,然后将其更改为类类型。我尝试过类似的事情:

Html.Kendo().Grid<(Type)Model.ObjectType>
Html.Kendo().Grid<typeof(Model.ObjectType)>
Run Code Online (Sandbox Code Playgroud)

...和其他愚蠢的方式。

我的最后一个问题是,是否可以通过某种方式诱使编译器将字符串或类似的东西视为项目中的类。

我也尝试过类似的方法:

Html.Kendo().Grid<IProduct>
Run Code Online (Sandbox Code Playgroud)

这种方法有效,但是这意味着我要在网格中使用的任何对象必须具有Product接口的所有字段。

作为最后的观察,我完成了这项工作,但是没有通过使用不同的语法来实现网格中内置的任何Delete / Create / Update操作:

@(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))
    )
)
Run Code Online (Sandbox Code Playgroud)

更新:

我找到了解决方案。

@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))
    )
)
Run Code Online (Sandbox Code Playgroud)

我要做的是摆脱Kendo提供的所有无用的标准函数(如Destroy或Create),因为它们需要带有Grid <'object type'>的合奏。

GridViewModel对象现在看起来像这样:

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

    public GridViewModel(Type type, string actionName)
    {
        ObjectType = type;
        ReadDataActionName = actionName;
    }
}
Run Code Online (Sandbox Code Playgroud)

其中,ReadDataActionName是负责返回Kendo网格可以读取的Json对象列表的动作名称。

然后,我创建了一些自定义命令,这些命令指向Jquery中的自定义函数,该自定义函数将一个非常复杂的对象作为参数发送,该对象具有(除其他所有功能之外)我单击的网格中的Json对象。

最后,最重要的是数据源中的.Read函数。那必须指向一个返回特殊类型的Json的函数(有关该Json类型的信息,请参见Kendo文档,您的操作必须在其演示示例中返回)。

因此,您不需要像看到的那样需要一个对象数组:

@(Html.Kendo().Grid(mockList)
    ...
)
Run Code Online (Sandbox Code Playgroud)

其中,mocklist是对象列表(空的和寂寞的-用来欺骗否则无法正常工作的功能)。

最后的结果是,我有一个通用网格,可以使用“删除”和“编辑”按钮来接受任何对象数组,这些按钮指向一个可以根据自己的喜好进行自定义的功能-它可以从局部视图中打开一个包含数据的弹出窗口,全视图或您想要的任何内容。我什至自定义了删除功能以删除Ajax帖子,而无需用户进行任何确认,并且完全可以使用。