65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 Kendo Grid 的示例

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.80/5 (25投票s)

2013年10月31日

CPOL

9分钟阅读

viewsIcon

229217

downloadIcon

8465

本文提供了一个使用 Kendo Grid 的示例。

引言

本文提供了一个使用 Kendo Grid 的示例。Kendo 为我们提供了许多 Web 工具,例如“DatePicker”、“NumericTextBox”和 Grid。在这些 Web 工具中,Grid 是最复杂的 Web 工具。本文旨在向您展示如何使用 Kendo Grid。此处的示例使用了开源版本的 Kendo。如果您已经购买了付费版本并且对其提供的功能感到满意,那么本文不适合您,因为您的版本使用起来要容易得多。但是,如果您乐于使用开源版本进行开发,可以阅读本文,更详细地了解 Kendo 的工作原理,并可能需要编写一些额外的代码。

背景

“Grid”是最常用的客户端 Web 控件之一。有许多基于 JavaScript 的 Grid 选项。在这些选项中,根据您需要的功能,Kendo Grid 不一定是最好的。但它相当易于使用,并且适合大多数应用程序场景。本文提供了一个使用 Kendo Grid 的示例。该示例是一个在 Visual Studio 2010 中编写的 MVC 2 应用程序。我非常清楚 MVC 的最新版本是 4,但为了让读者更容易下载和运行示例,我将其保持在较低版本,以防他们没有更高版本的 Visual Studio 和环境。在此示例中,我将向您展示以下内容:

  • 如何在您的 Web 应用程序中设置 Kendo 环境;
  • 如何实现一个基本的 Keno Grid;
  • 如何在 Grid 上实现排序和过滤;
  • 如何创建一个基本的事件监听器来处理诸如双击 Grid 行之类的事件。
示例使用了服务器绑定,我认为当您拥有相对庞大且动态的数据集时,服务器绑定更容易管理。

在应用程序中设置 Kendo 环境

Kendo 有几个版本。本示例中使用的是开源版本。

  • 您需要“kendo.common.min.css”文件。除了这个文件,Kendo 还为我们提供了许多控制 Kendo 工具外观的选项。在本示例中,我选择了默认外观,因此我还包含了“kendo.default.min.css”文件以及该 CSS 文件在“Default”文件夹中关联的图像文件。
  • Kendo 构建在 jQuery 之上,因此我们需要 jQuery 文件“jquery-2.0.3.min.js”。
  • 您还需要从 Kendo 项目中获取“kendo.web.min.js”文件。
本示例使用的 Kendo 版本是开源版本,版本号为“2013.2.716”。

要在 Grid 中显示的数据

“StudentRepository.cs”作为要显示在 Kendo Grid 中的数据的存储库。

using System;
using System.Collections.Generic;
using System.Text;
    
namespace KendoGridExample.Models
{
    public class Student
    {
        public int? Id { get; set; }
        public string LastName { get; set; }
        public string FirstName { get; set; }
        public int Score { get; set; }
        public bool Active { get; set; }
    }
    
    public static class StudentRepository
    {
        public static List<Student> Students { get; private set; }
        static StudentRepository()
        {
            Func<char, string> rep4 = x =>
            {
                var result = new StringBuilder();
                for (var i = 0; i < 5; i++)
                {
                    result.Append(x);
                }
                return result.ToString();
            };
    
            Students = new List<Student>();
            var rand = new Random();
            for(var i = 1; i <= 1000; i++)
            {
                var m = (i - 1)%26;
                var lascii = m + 65;
                var student = new Student()
                {
                    Id = i,
                    LastName = rep4((char)lascii),
                    FirstName = " First Name " + i % 20,
                    Score = 60 + (int) Math.Round(rand.NextDouble()*40),
                    Active = i % 3 == 0
                };
    
                Students.Add(student);
            }
        }
    }
} 

静态类“StudentRepository”将使用 1000 个随机生成的学生进行初始化。我将在本示例中向您展示如何将这些学生显示在 Kendo Grid 中。

支持排序和过滤的类

“KendoGridSorter.cs”和“LinqSortingUtility.cs”文件支持 Kendo Grid 的排序功能。

using System;
using System.Collections.Generic;
using System.Web;
    
namespace KendoGridExample.KendoGridUtilities
{
    public class KendoGridSorterCollection
    {
        public List<KendoGridSorter> Sorters { get; private set; }
        private KendoGridSorterCollection()
        {
            Sorters = new List<KendoGridSorter>();
        }
    
        public static KendoGridSorterCollection BuildEmptyCollection()
        {
            return new KendoGridSorterCollection();
        }
    
        public static KendoGridSorterCollection BuildCollection(HttpRequestBase request)
        {
            var collection = BuildEmptyCollection();
    
            var idex = 0;
            while(true)
            {
                var sorter = new KendoGridSorter()
                {
                    Field = request.Params["sort[" + idex + "][field]"],
                    Direction = request.Params["sort[" + idex + "][dir]"] 
                };
    
                if (sorter.Field == null) { break; }
                collection.Sorters.Add(sorter);
                idex++;
            }
    
            return collection;
        }
    }
    
    public class KendoGridSorter
    {
        public string Field { get; set; }
        public string Direction { get; set; }
    }
} 
using System;
using System.Linq;
    
using System.Collections.Generic;
    
namespace KendoGridExample.KendoGridUtilities
{
    public static class LinqSortingUtility
    {
        public static IEnumerable<T> MultipleSort<T>(this IEnumerable<T> data,
          List<KendoGridSorter> sortExpressions)
        {
            if ((sortExpressions == null) || (sortExpressions.Count <= 0))
            {
                return data;
            }
    
            IEnumerable<T> query = from item in data select item;
            IOrderedEnumerable<T> orderedQuery = null;
    
            for (int i = 0; i < sortExpressions.Count; i++)
            {
                var index = i;
                Func<T, object> expression = item => item.GetType()
                                .GetProperty(sortExpressions[index].Field)
                                .GetValue(item, null);
    
                if (sortExpressions[index].Direction == "asc")
                {
                    orderedQuery = (index == 0)
                        ? query.OrderBy(expression)
                            : orderedQuery.ThenBy(expression);
                }
                else
                {
                    orderedQuery = (index == 0)
                        ? query.OrderByDescending(expression)
                            : orderedQuery.ThenByDescending(expression);
                }
            }
    
            query = orderedQuery;
    
            return query;
        }
    }
} 
  • “KendoGridSorterCollection”类中的工厂方法“BuildCollection”根据 Kendo Grid 从“HttpRequestBase”对象发送的请求对象构建一个“KendoGridSorterCollection”类的实例。如果成功,则“KendoGridSorterCollection”对象将包含一个“KendoGridSorter”对象列表,这些对象告诉我们用户希望如何对 Grid 数据进行排序。
  • “MultipleSort”是“IEnumerable”集合上的一个扩展方法。我们可以通过传递“KendoGridSorter”对象列表来调用此方法来对数据进行排序。
  • 这两个类支持多列排序。

“KendoGridFilter.cs”和“LinqFilteringUtility.cs”文件支持 Kendo Grid 的过滤功能。

using System.Collections.Generic;
using System.Web;
    
namespace KendoGridExample.KendoGridUtilities
{
    public class KendoGridFilterCollection
    {
        public List<KendoGridFilter> Filters { get; private set; }
        private KendoGridFilterCollection()
        {
            Filters = new List<KendoGridFilter>();
        }
    
        public static KendoGridFilterCollection BuildEmptyCollection()
        {
            return new KendoGridFilterCollection();
        }
    
        public static KendoGridFilterCollection BuildCollection(HttpRequestBase request)
        {
            var collection = BuildEmptyCollection();
    
            var idex = 0;
            while (true)
            {
                var filter = new KendoGridFilter()
                {
                    Field = request.Params["filter[filters][" + idex + "][field]"],
                    Operator = request.Params["filter[filters][" + idex + "][operator]"],
                    Value = request.Params["filter[filters][" + idex + "][value]"]
                };
    
                if (filter.Field == null) { break; }
                collection.Filters.Add(filter);
                idex++;
            }
    
            return collection;
        }
    }
    
    public class KendoGridFilter
    {
        public string Field { get; set; }
        public string Operator { get; set; }
        public string Value { get; set; }
    }
} 
using System;
using System.Collections.Generic;
using System.Linq;
    
namespace KendoGridExample.KendoGridUtilities
{
    public static class LinqFilteringUtility
    {
        public static IEnumerable<T> MultipleFilter<T>(this IEnumerable<T> data,
          List<KendoGridFilter> filterExpressions)
        {
            if ((filterExpressions == null) || (filterExpressions.Count <= 0))
            {
                return data;
            }
    
            IEnumerable<T> filteredquery = from item in data select item;
    
            for (int i = 0; i < filterExpressions.Count; i++ )
            {
                var index = i;
    
                Func<T, bool> expression = item =>
                    {
                        var filter = filterExpressions[index];
                        var itemValue = item.GetType()
                            .GetProperty(filter.Field)
                            .GetValue(item, null);
    
                        if (itemValue == null)
                        {
                            return false;
                        }
    
                        var value = filter.Value;
                        switch (filter.Operator)
                        {
                            case "eq":
                                return itemValue.ToString() == value;
                            case "startswith":
                                return itemValue.ToString().StartsWith(value);
                            case "contains":
                                return itemValue.ToString().Contains(value);
                            case "endswith":
                                return itemValue.ToString().EndsWith(value);
                        }
    
                        return true;
                    };
    
                filteredquery = filteredquery.Where(expression);
            }
    
            return filteredquery;
        }
    }
} 
  • 与“KendoGridSorterCollection”类类似,“KendoGridFilterCollection”类中的工厂方法“BuildCollection”根据 Kendo Grid 从“HttpRequestBase”对象发送的请求对象构建一个“KendoGridFilterCollection”类的实例。如果成功,则“KendoGridFilterCollection”对象将包含一个“KendoGridFilter”对象列表,这些对象告诉我们用户希望如何过滤数据。
  • “MultipleFilter”是“IEnumerable”集合上的一个扩展方法。我们可以通过传递“KendoGridFilter”对象列表来调用此方法来过滤数据。
  • “MultipleFilter”方法仅实现了“eq”、“startswith”、“contains”和“endswith”操作。如果您想支持更多操作,可以修改此扩展方法。
  • 这两个类支持多列过滤。

服务器端代码

本文中的示例使用服务器绑定。服务器将发送数据以在 Grid 中显示。“HomeController.cs”文件实现如下。

using System.Linq;
using System.Web.Mvc;
using KendoGridExample.KendoGridUtilities;
using KendoGridExample.Models;
    
namespace KendoGridExample.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }
    
    public ActionResult GetAStudent(int id)
        {
            var student = StudentRepository.Students.Single(s => s.Id == id);
            return PartialView("Student", student);
        }
    
        public ActionResult LoadStudents(int page, int pageSize, int take
        , bool? activeOnly)
        {
            var sorterCollection = KendoGridSorterCollection.BuildCollection(Request);
            var filterCollection = KendoGridFilterCollection.BuildCollection(Request);
    
            var students = (!(activeOnly ?? false))
                               ? StudentRepository.Students
                               : StudentRepository.Students.Where(s => s.Active);
            var filteredStudents = students.MultipleFilter(filterCollection.Filters);
            var sortedStudents = filteredStudents.MultipleSort(sorterCollection.Sorters)
                    .ToList();
            var count = sortedStudents.Count();
            var data = (from v in sortedStudents.Skip((page - 1) * pageSize)
                            .Take(pageSize) select v).ToList();
    
            var jsonData = new { total = count, data };
            return Json(jsonData, JsonRequestBehavior.AllowGet);
        }
    }
}   
  • “Index”方法加载应用程序的主 MVC 视图页面。
  • “GetAStudent”方法仅返回一个包含单个学生信息的局部视图。由于本文是关于 Kendo Grid 的,我不会花太多时间来通过 Ajax 调用将局部视图返回到网页。如果您感兴趣,可以参考我之前的文章《使用 jQuery 和 MVC 加载干净的 HTML 片段》。
  • “LoadStudents”方法是服务器将学生列表发送到 Kendo Grid 以显示的地方。当 Kendo Grid 从服务器检索数据时,它会传递服务器加载数据所需的信息。在“LoadStudents”方法中,排序和过滤信息从“Request”对象中获取,然后用于过滤和排序学生。Kendo Grid 不需要“LoadStudents”方法返回所有学生。它只需要在页面上显示的学生列表。除了学生总数之外,数据还会作为JSON结果返回。

客户端代码

要使用 Kendo Grid,我们需要在“Index.aspx”页面中链接所需的 CSS 和 JavaScript 文件。

我们不需要jQuery UI来使用 Kendo Grid。我包含“jquery-ui.min.js”文件的原因是为了使用其“dialog”窗口显示单个学生的信息,以向您展示如何处理 Grid 行上的双击事件。 “Index.aspx”页面的 HTML 内容如下。

<body>
    <div id="dialog" style="display: none"></div>
    <div>
        <div><input type="checkbox" id="chkShowActive" checked="checked"
                onclick="return GridExample.Refresh()"/>
            Show active students only</div>
        <div id="GridContainer"></div>
    </div>
</body>  
  • “dialog”div 将由jQuery UI用于显示一个对话框窗口,以显示单个学生的信息。
  • “chkShowActive”复选框将用于向您展示如何刷新 Kendo Grid 以及如何将更新的数据发送到服务器。
  • “GridContainer”将被 Kendo 用来创建 Kendo Grid 以显示学生的信息。
用于创建和操作 Kendo Grid 的 JavaScript 代码如下。
var gridReadUrl = '<%=Url.Action("LoadStudents") %>';
var getStudentUrl = '<%=Url.Action("GetAStudent") %>';
    
var GridExample = function () {
    var initialize = function() {
        var container = $('#GridContainer').html('<div></div>');
        var grid = $('div', container);
    
        var filterOption = {
            extra: false,
            operators: {
                string: {
                    eq: "Is Equal To",
                    startswith: "Starts With",
                    contains: "Contains",
                    endswith: "Ends With"
                }
            }
        };
    
        var columnOptions = [
            {
                field: "Id",
                title: "Id",
                width: 100,
                type: "integer",
                filterable: false
            },
            {
                field: "LastName",
                title: "Last Name",
                filterable: filterOption
            },
            {
                field: "FirstName",
                title: "First Name",
                filterable: filterOption
            },
            { field: "Score", title: "Score", filterable: false },
            { field: "Active", title: "Active", filterable: false }
        ];
    
        var gridOptions = {
            dataSource: {
                transport: {
                    read: {
                        url: gridReadUrl,
                        type: "POST",
                        data: function() {
                            return {
                                activeOnly: $('#chkShowActive').is(':checked')
                            };
                        }
                    }
                },
                schema: { data: "data", total: "total", model: { id: "Id" } },
                serverPaging: true,
                serverSorting: true,
                serverFiltering: true
            },
            columns: columnOptions,
            height: 300,
            sortable: { mode: "multiple", allowUnsort: true },
            filterable: true,
            pageable: {
                pageSize: 30,
                refresh: true,
                messages: {
                    refresh: "Refresh the grid"
                }
            }
        };
    
        grid.kendoGrid(gridOptions)
            .delegate("tbody>tr", "dblclick", function(e) {
                var row = e.currentTarget;
                var selectedItem = grid.data("kendoGrid").dataItem(row);
    
                var ajax = $.ajax({
                    url: getStudentUrl,
                    type: "POST",
                    data: { id: selectedItem.Id },
                    dataType: "html"
                });
    
                ajax.success(function(data) {
                    var dialog = $('#dialog');
                    dialog.html(data);
                    dialog.dialog({
                        modal: true
                    });
                });
            });
    };
    
    var refresh = function () {
        var grid = $('#GridContainer>div');
        if (grid.length < 1) {
            return;
        }
    
        grid.data("kendoGrid").dataSource.read();
    };
    
    return {
        Initialize: initialize,
        Refresh: refresh
    };
} ();
    
$(document).ready(function () {
    GridExample.Initialize();
}); 

“GridExample”变量是一个 JSON 对象,它公开了“Initialize”和“Refresh”两个函数。“Initialize”函数初始化 Kendo Grid,“Refresh”函数刷新 Grid。要初始化 Kendo Grid,我们可以简单地调用 Grid 容器 div 上的 jQuery 对象的“kendoGrid”函数,并传递一个 JSON 对象来指示我们希望 Grid 如何工作。传递给“kendoGrid”函数的重要信息包括以下内容:

  • 加载要显示的数据的 URL 和HTTP 方法
  • 从服务器加载数据时要传递给服务器的附加数据;
  • 我们希望在 Grid 中显示的列以及我们希望它们如何显示;
  • Grid 的尺寸和分页信息;
  • 排序和过滤配置。

要处理 Grid 行上的双击事件,我们可以为每一行关联一个委托。在委托中,我们首先检索双击学生的 ID,然后发出 Ajax 调用以加载包含学生信息的局部视图。然后,该局部视图将显示在 jQuery UI 对话框框中。

运行应用程序

正如 Kendo 的设计理念那样简单,我们现在完成了示例应用程序,并且拥有了一个功能齐全的 Kendo Grid。然后我们可以进行测试运行。当网页首次加载时,Kendo 会发出一个 Ajax 调用来检索要在网页中显示的信息。

默认情况下,我们只显示活动的学员。如果您取消选中“仅显示活动学员”复选框,Grid 将刷新以显示活动和非活动学员。

然后,我们可以通过应用一些过滤文本并单击某些列的标题来尝试 Kendo Grid 的过滤和排序功能。

如果我们双击 Grid 中的某一行,事件将被处理,该学生的学信息将通过局部视图加载,并显示在 jQuery UI 对话框框中。

Kendo Grid 的编辑功能如何?

Kendo Grid 不仅限于显示数据。它附带了一套全面的编辑功能。但我不会在本示例中探讨这些功能。根据我的经验,我发现实现自己的弹出对话框来添加新数据和编辑现有数据项更容易。我们可以在弹出窗口中轻松添加文本框或其他输入控件,以允许用户更改数据。我们可以使用 Ajax 调用将数据发送到服务器以更新数据源。如果 Ajax 调用成功,我们可以简单地刷新 Kendo Grid 以显示更新后的数据。

关注点

  • 该示例向您展示了如何在您的应用程序中设置使用 Kendo Web 控件的环境。它还向您展示了如何实现 Kendo Grid 的一些基本功能。
  • 示例实现了 Linq 中的排序和过滤。如果您的应用程序背后有数据库,您可以选择在数据库中实现排序和过滤。根据我自己的测试,我发现本文提供的用于多列排序和过滤的扩展方法非常高效。
  • 该示例没有探讨 Kendo 提供的编辑功能,因为我个人更倾向于实现自己的对话框弹出窗口来实现添加新项和编辑现有项的功能。
  • Kendo 有不同的版本,其中一些是付费版本。这些版本应该比开源版本更容易使用,因此我强烈建议您尝试一下。
  • 我希望您喜欢我的文章,希望本文能以某种方式帮助您。

历史

首次修订 - 2013/10/31

© . All rights reserved.