概述
前几节我们学习了怎么在MVC 3.0程序里面实现一个数据表格,以及在数据表格中加入了排序、分页和筛选等功能,对于MVC视图中标记的呈现,我们的办法是在一个<table>中通过foreach遍历数据集,来输出一对对的<td>来显示每行的数据。虽然这种办法是可行的,但是如果数据列过多就显得过于牵强。我们就会想如果有类似的控件来完成我们的Grid那就再好不过了。
背景
我们都知道ASP.NET MVC框架包含一个HtmlHelper类,该类为我们视图界面中渲染Html内容提供了支持,比如创建操作链接 Html.ActionLink,文本框Html.TextBoxFor等,都是通过HtmlHelper类的扩展方法来实现的。
网络上有很多基于MVC的开源项目,比如mvccontrib,这些项目都为ASP.NET MVC框架增加了各种功能,包括创建表格及对表格数据的排序、分页等功能,使得我们使用起来更加方便快捷。
创建Controller
同样我们是用以前的数据集作为数据源,所以创建一个心的Controller使用方法来调用和显示内容即可。
右击 Controller文件夹--添加--控制器
命名为:MvcContribController
添加如下代码
using System.Collections.Generic; using System.Web.Mvc; using MVC3.Grid.Models; using MvcContrib.UI.Grid; using MvcContrib.Sorting; namespace MVC3.Grid.Controllers { public class MvcContribController : BaseController { // // GET: /MvcContrib/ public ActionResult Index(GridSortOptions model) { ViewBag.model = model; IEnumerable<Employee> list = DataContext.Employee; if (!string.IsNullOrEmpty(model.Column)) { list = list.OrderBy(model.Column, model.Direction); } return View(list); } } }
注意此处必须添加MvcContrib.dll
可以在mvccontrib网站上下载
添加视图
为Index方法添加视图,选择Model中的Employee作为强类型
添加代码
@model IEnumerable<MVC3.Grid.Models.Employee> @{ ViewBag.Title = "Index"; Layout = "~/Views/Shared/_Layout.cshtml"; } <h2>排序列表</h2> @using MvcContrib.UI.Grid @Html.Grid(Model).Columns(column => { column.For(p => p.EmployeeNO); column.For(p => p.EmployName); column.For(p => p.Sex); column.For(p => p.Birthday); column.For(p => p.Marital); } )
运行效果
可以看到,基本的表格算是有了,可是还没有样式,有点丑。
添加样式
MvcContrib为我们提供了Attributes方法,我们可以随意给表格或者其中任何一个标签添加样式。
修改代码
@using MvcContrib.UI.Grid @Html.Grid(Model).Columns(column => { column.For(p => p.EmployeeNO); column.For(p => p.EmployName); column.For(p => p.Sex); column.For(p => p.Birthday); column.For(p => p.Marital); } ).Attributes( @class=>"right",@width => "100%", @border => "1", @style => "text-align:center;border-collapse:collapse")
运行效果
可以看到样式已经起作用了。
修改表头
此时我们的表头是默认的模型属性名称,看起来相当的不爽,所以我们要自己定义表头
MvcContrib为我们提供了Named方法,可以让我们自定义表头
修改代码
@using MvcContrib.UI.Grid @Html.Grid(Model).Columns(column => { column.For(p => p.EmployeeNO).Named("编号"); column.For(p => p.EmployName).Named("姓名"); column.For(p => p.Sex).Named("性别"); column.For(p => p.Birthday).Named("出生年月"); column.For(p => p.Marital).Named("是否婚配"); } ).Attributes( @class=>"right",@width => "100%", @border => "1", @style => "text-align:center;border-collapse:collapse")
运行效果
上图我们可以看出表头已经改变
格式化字符串
在表格里面很多数据都不规范,如:出生年月后面的完全不需要。
MvcContrib为我们提供了Format方法,来定义显示数据的格式。
修改代码
@using MvcContrib.UI.Grid @Html.Grid(Model).Columns(column => { column.For(p => p.EmployeeNO).Named("编号"); column.For(p => p.EmployName).Named("姓名"); column.For(p => p.Sex).Named("性别"); column.For(p => p.Birthday).Format("{0:yyyy年MM月dd日}").Named("出生年月"); column.For(p => p.Marital).Named("是否婚配"); } ).Attributes( @class=>"right",@width => "100%", @border => "1", @style => "text-align:center;border-collapse:collapse")
运行效果
效果是相当给力啊。。。
输出判断
很多时候我们需要将一些标识性的字符改为我们常见的语句,如:是否婚配的0和1,看起来有点生硬。
MvcContrib在生成列的时候使用lamda表达式,在这里可以做判断。
修改代码:
@using MvcContrib.UI.Grid @Html.Grid(Model).Columns(column => { column.For(p => p.EmployeeNO).Named("编号"); column.For(p => p.EmployName).Named("姓名"); column.For(p => p.Sex).Named("性别"); column.For(p => p.Birthday).Format("{0:yyyy年MM月dd日}").Named("出生年月"); column.For(p => p.Marital == "1" ? "是" : "否").Named("是否婚配"); } ).Attributes( @class=>"right",@width => "100%", @border => "1", @style => "text-align:center;border-collapse:collapse")
运行效果
可以看到一个完整的表格已经做好了 。下面我们来进行排序。
表格排序
在MvcContrib中为我们提供了Sort方法,他需要我们从页面传递一个GridSortOptions类型的参数给Action,读取他的Column和Direction来完成排序工作的。
默认情况下所有的列都会被加上排序功能,我们可以使用Sortable(false)来禁用列的排序。
看代码
@using MvcContrib.UI.Grid @Html.Grid(Model).Sort(ViewBag.model as GridSortOptions).Columns(column => { column.For(p => p.EmployeeNO).Named("编号"); column.For(p => p.EmployName).Named("姓名"); column.For(p => p.Sex).Named("性别"); column.For(p => p.Birthday).Format("{0:yyyy年MM月dd日}").Named("出生年月"); column.For(p => p.Marital == "1" ? "是" : "否").Named("是否婚配").Sortable(false); } ).Attributes( @class=>"right",@width => "100%", @border => "1", @style => "text-align:center;border-collapse:collapse")
看效果
除了是否婚配其他列都可以排序
这样我们的排序就做好了,下面我们继续看看分页怎么做。
表格分页
在MvcContrib里我们只需要知道当前page的索引即可读取上下页的数据。
修改Index方法
using System.Collections.Generic; using System.Web.Mvc; using MVC3.Grid.Models; using MvcContrib.Pagination; using MvcContrib.UI.Grid; using MvcContrib.Sorting; namespace MVC3.Grid.Controllers { public class MvcContribController : BaseController { // // GET: /MvcContrib/ public ActionResult Index(int? page, GridSortOptions model) { ViewBag.model = model; IEnumerable<Employee> list = DataContext.Employee; if (!string.IsNullOrEmpty(model.Column)) { list = list.OrderBy(model.Column, model.Direction); } list = list.AsPagination(page ?? 1, 5); return View(list); } } }
我们可以看到,上面的方法只是在原来的基础上面添加了一个参数和一个默认的索引页和每页显示数据的条数。
运行起来看看
发现我们的数据从以前的8条变为现在的5条,这说明我们的分页已经是ok了的,只是在界面中缺少了,分页控件而已。
在MvcContrib里面为我们提供了Html.Pager(Model)这样的扩展方法可以实现分页,但是该模型必须是IPagination类型的,该类型是继承了IEnumerable的,需要添加命名空间MvcContrib.Pagination
修改视图完整代码
@model IPagination<MVC3.Grid.Models.Employee> @using MvcContrib.UI.Grid; @using MvcContrib.UI.Pager; @using MvcContrib.Pagination; @{ ViewBag.Title = "Index"; Layout = "~/Views/Shared/_Layout.cshtml"; } <h2>排序列表</h2> @Html.Grid(Model).Sort(ViewBag.model as GridSortOptions).Columns(column => { column.For(p => p.EmployeeNO).Named("编号"); column.For(p => p.EmployName).Named("姓名"); column.For(p => p.Sex).Named("性别"); column.For(p => p.Birthday).Format("{0:yyyy年MM月dd日}").Named("出生年月"); column.For(p => p.Marital == "1" ? "是" : "否").Named("是否婚配").Sortable(false); } ).Attributes(@class => "right", @width => "100%", @border => "1", @style => "text-align:center;border-collapse:collapse") @Html.Pager(Model).First("首页").Next("下一页").Previous("上一页").Last("尾页").Format("总{2}条,当前{0}-{1}条 ")
运行效果
这样分页就做好了。。。
总结
对于MVC框架的扩展有很多,我只是选择了其中的一个作为例子,只是学习他们的封装的想法,大家可以去网站上下载看看源代码,或许你会收获很多。