WebGrid控件的高级使用

在笔记三中记录了WebGrid的简单使用,但实际工作中并不能满足开发要求,比如:考虑到性能,要求服务器端分页,而不是查出所有数据来进行简单的客户端页面分页;要在排序时,给列标题显示不同图像等等,都不是直接就能满足的,这里记录下对WebGrid进行的较高层次的使用。
一.服务器端分页处理
在演示服务端分页之前,先做一些简单的准备工作:
1.新建一个空的MVC 3项目,添加一个名为“GridController”的控制器;
2.在Model中增加一个“Movie”类;
代码如下:
   public class Movie{//主键public int Id { get; set; }//电影名称public string MovieName { get; set; }//票价public decimal TicketPrice { get; set; }//演播厅public string ShowAddress { get; set; }//上线日期public DateTime ShowTime { get; set; }//领衔主演public string Starring { get; set; }}
3.给控制器“GridController”的默认Index方法添加一个基于“Movie”的强类型视图,支架模板选择List;
为方便测试,修改Index方法为:
        public ActionResult Index(){List<Movie> movies = new List<Movie>(){new Movie(){ Id=1, MovieName="晚秋", Starring="汤唯", ShowAddress="苏州科文中心", ShowTime=DateTime.Parse("2014-4-10 15:00:00"), TicketPrice=25.5M},new Movie(){ Id=2, MovieName="神偷奶爸", Starring="XXX1", ShowAddress="观前街影城", ShowTime=DateTime.Parse("2014-5-1 14:30:00"), TicketPrice=20.5M},new Movie(){ Id=3, MovieName="Yes Man", Starring="XXX2", ShowAddress="苏州印象城", ShowTime=DateTime.Parse("2014-5-2 14:25:00"), TicketPrice=21.5M},new Movie(){ Id=4, MovieName="里约大冒险", Starring="未知", ShowAddress="苏州石路", ShowTime=DateTime.Parse("2014-5-3 14:40:00"), TicketPrice=22.5M},new Movie(){ Id=5, MovieName="疯狂原始人", Starring="未知1", ShowAddress="观前街影城", ShowTime=DateTime.Parse("2014-5-4 14:00:00"), TicketPrice=23.5M},new Movie(){ Id=6, MovieName="活着", Starring="葛优、巩俐", ShowAddress="观前街影城", ShowTime=DateTime.Parse("2014-5-5 14:00:00"), TicketPrice=24.5M},new Movie(){ Id=7, MovieName="北京遇上西雅图", Starring="汤唯", ShowAddress="观前街影城", ShowTime=DateTime.Parse("2014-5-6 14:00:00"), TicketPrice=26.5M},new Movie(){ Id=8, MovieName="人在囧途", Starring="徐峥", ShowAddress="XXX街影城", ShowTime=DateTime.Parse("2014-5-7 14:00:00"), TicketPrice=27.5M},new Movie(){ Id=9, MovieName="神探狄仁杰", Starring="未知", ShowAddress="观前街影城", ShowTime=DateTime.Parse("2014-5-8 14:00:00"), TicketPrice=28.5M},new Movie(){ Id=10, MovieName="里约大冒险2", Starring="未知", ShowAddress="观前街影城", ShowTime=DateTime.Parse("2014-5-9 14:00:00"), TicketPrice=29.5M},};return View(movies);}
4.为了使WebGrid界面美观一些,再添加一个CSS文件,代码如下:
body {
}
table {  border: solid 1px #e8eef4;  border-collapse: collapse;
}  table td {  padding: 5px;  border: solid 1px #e8eef4;  width:100px;  text-align:center ;background-color:orange;
}  table th {  padding: 6px 5px;  text-align:center;  background-color:#CC99CC;  border: solid 1px #e8eef4;
}  .rowStyle
{  background-color: #E8E8E8;  color: #000;
}  .gridhead {  background-color:yellow;  font-weight:bold;  text-align:center;
} 

按照原先的简单做法,修改视图文件代码为:

@model IEnumerable<MvcWebGrid.Models.Movie>
@{ViewBag.Title = "我的WebGrid";
}<h2>我的WebGrid示例</h2>@{var grid = new WebGrid(source: Model,rowsPerPage: 4);}@grid.GetHtml(
tableStyle: "table",
headerStyle: "gridhead",
mode:WebGridPagerModes.All,
firstText:"首页",
lastText:"尾页",
previousText:"上一页",
nextText:"下一页",columns:
grid.Columns(grid.Column("Id", "序号"),grid.Column("MovieName", "电影名"),grid.Column("Starring", "影院地址"),grid.Column("TicketPrice", "票价"),grid.Column("ShowAddress", "影院地址"),grid.Column("ShowTime", "上映日期")
)
)
运行网页,URL后加上:/grid
效果如下:

到此为止,是以前的做法,可以在页面进行分页,也可以排序,但是问题来了:
如果我后台数据量很大,假如有100万条,在每次重新运行该网页时,都会从数据库中查询出100W条数据,上面的做法只不过在客户端页面分页了一下,显示了4条,实际上我后台却作了查询100W条数据的工作量,而我们也许仅仅只要看某一页而已...
所以上面的分页做法肯定是不能满足性能要求的,这就要考虑使用服务端分页。
做法很简单,就是利用WebGrid页(如:第n页)和每页需要显示的行数(如:4行)来取数据:
举个简单的例子:如果我要看第1页,那么我只需要从数据库中查出前1~4条数据即可;要看第2页,只需要从数据库中查出从5~8条数据即可,依此类推,要看第n页,只要从数据库中查出第(n-1)*4+1~4*n条数据即可。
接下来的问题就是考虑:如何让数据库去执行查询指定行的命令,其实很简单,不管用的是LINQ to Sql还是其它形式,无非就是在前台查询指令,获得了WebGrid页和每页需要显示的行数的前提下,将指令转化成查询指定行的SQL。
SqlServer查询指定行的SQL大家应该都知道的,如:
SELECT * FROM
(SELECT ROW_NUMBER() OVER( ORDER BY 排序的字段 ) AS 序号,表.* FROM 表
) tmp
WHERE tmp.序号 between xxx to xxxx
这里不用管它,只要知道最终是转化成这样的SQL即可。

现在的问题就是:我要在模型绑定时,知道WebGrid页---即用户点击了分页中的哪一页!这个十分简单,可以利用户点击下一页或上一页时,借助模型绑定,将webgrid页以参数形式传给action方法,即本例的Index方法,首先我得添加一个int型的参数:

        public ActionResult Index(int page=1){//...}

其次,有了这个参数之后,后台就知道用户选了第几页,我后台就可以根据前面的算法,算出要查询第m~n行数据;

最后,后台查出数据之后,返回给页面数据,即Model,得借助webgrid的Bind方法动态绑定数据,由于分页还需要知道数据总行数来确定按钮个数,所以Model里必须要包含一个从后台查出数据的总行数,综上所述,我的Index视图就不能再是绑定原先的了,以下是做法:
1)在Model文件夹增加一个类,名称为“SelectMovies”:
    public class SelectMovies{//根据第n页查出的数据public List<Movie> selectMovies { get; set; }//数据总量public int totalCount { get; set; }}

2)修改Index方法为:

     public ActionResult Index(int page=1){const int totalCount = 10;const int rowsPerPage = 4;List<Movie> movies = new List<Movie>(){new Movie(){ Id=1, MovieName="晚秋", Starring="汤唯", ShowAddress="苏州科文中心", ShowTime=DateTime.Parse("2014-4-10 15:00:00"), TicketPrice=25.5M},new Movie(){ Id=2, MovieName="神偷奶爸", Starring="XXX1", ShowAddress="观前街影城", ShowTime=DateTime.Parse("2014-5-1 14:30:00"), TicketPrice=20.5M},new Movie(){ Id=3, MovieName="Yes Man", Starring="XXX2", ShowAddress="苏州印象城", ShowTime=DateTime.Parse("2014-5-2 14:25:00"), TicketPrice=21.5M},new Movie(){ Id=4, MovieName="里约大冒险", Starring="未知", ShowAddress="苏州石路", ShowTime=DateTime.Parse("2014-5-3 14:40:00"), TicketPrice=22.5M},new Movie(){ Id=5, MovieName="疯狂原始人", Starring="未知1", ShowAddress="观前街影城", ShowTime=DateTime.Parse("2014-5-4 14:00:00"), TicketPrice=23.5M},new Movie(){ Id=6, MovieName="活着", Starring="葛优、巩俐", ShowAddress="观前街影城", ShowTime=DateTime.Parse("2014-5-5 14:00:00"), TicketPrice=24.5M},new Movie(){ Id=7, MovieName="北京遇上西雅图", Starring="汤唯", ShowAddress="观前街影城", ShowTime=DateTime.Parse("2014-5-6 14:00:00"), TicketPrice=26.5M},new Movie(){ Id=8, MovieName="人在囧途", Starring="徐峥", ShowAddress="XXX街影城", ShowTime=DateTime.Parse("2014-5-7 14:00:00"), TicketPrice=27.5M},new Movie(){ Id=9, MovieName="神探狄仁杰", Starring="未知", ShowAddress="观前街影城", ShowTime=DateTime.Parse("2014-5-8 14:00:00"), TicketPrice=28.5M},new Movie(){ Id=10, MovieName="里约大冒险2", Starring="未知", ShowAddress="观前街影城", ShowTime=DateTime.Parse("2014-5-9 14:00:00"), TicketPrice=29.5M},};var result = (from ms in movies select ms).Skip((page - 1) * rowsPerPage).Take(rowsPerPage);SelectMovies sm = new SelectMovies(){selectMovies = result.ToList(),totalCount=totalCount};return View(sm);}

3)修改Index视图:

@model MvcWebGrid.Models.SelectMovies@{ViewBag.Title = "我的WebGrid";
}<h2>我的WebGrid示例</h2>@{var grid = new WebGrid(source: null,rowsPerPage: 4);grid.Bind(Model.selectMovies, rowCount: Model.totalCount, autoSortAndPage: false);
}@grid.GetHtml(
tableStyle: "table",
headerStyle: "gridhead",
mode:WebGridPagerModes.All,
firstText:"首页",
lastText:"尾页",
previousText:"上一页",
nextText:"下一页",columns:
grid.Columns(grid.Column("Id", "序号"),grid.Column("MovieName", "电影名"),grid.Column("Starring", "影院地址"),grid.Column("TicketPrice", "票价"),grid.Column("ShowAddress", "影院地址"),grid.Column("ShowTime", "上映日期")
)
)
编译运行,在Index方法中加个断点,可以看到每次供视图绑定的新模型中,仅仅只有4条数据,而不是起初的10条:
到目前为止,基本实现了服务端分页,但是又存在另一个问题,那就是排序被禁用了,如果还原那将不能实现服务端分页,接下来介绍如何在使用服务端分页的同时还能排序。
很简单,只要模型绑定时,给action方法提供两个参数:一个是排序字段,一个是排序方向(正/反排序)
这里只要修改Index方法的参数及代码实现,不过需要通过反射实现动态排序:
      public ActionResult Index(int page=1,string sort="Id",string sortDir="ASC"){const int totalCount = 10;const int rowsPerPage = 4;List<Movie> movies = new List<Movie>(){new Movie(){ Id=1, MovieName="晚秋", Starring="汤唯", ShowAddress="苏州科文中心", ShowTime=DateTime.Parse("2014-4-10 15:00:00"), TicketPrice=25.5M},new Movie(){ Id=2, MovieName="神偷奶爸", Starring="XXX1", ShowAddress="观前街影城", ShowTime=DateTime.Parse("2014-5-1 14:30:00"), TicketPrice=20.5M},new Movie(){ Id=3, MovieName="Yes Man", Starring="XXX2", ShowAddress="苏州印象城", ShowTime=DateTime.Parse("2014-5-2 14:25:00"), TicketPrice=21.5M},new Movie(){ Id=4, MovieName="里约大冒险", Starring="未知", ShowAddress="苏州石路", ShowTime=DateTime.Parse("2014-5-3 14:40:00"), TicketPrice=22.5M},new Movie(){ Id=5, MovieName="疯狂原始人", Starring="未知1", ShowAddress="观前街影城", ShowTime=DateTime.Parse("2014-5-4 14:00:00"), TicketPrice=23.5M},new Movie(){ Id=6, MovieName="活着", Starring="葛优、巩俐", ShowAddress="观前街影城", ShowTime=DateTime.Parse("2014-5-5 14:00:00"), TicketPrice=24.5M},new Movie(){ Id=7, MovieName="北京遇上西雅图", Starring="汤唯", ShowAddress="观前街影城", ShowTime=DateTime.Parse("2014-5-6 14:00:00"), TicketPrice=26.5M},new Movie(){ Id=8, MovieName="人在囧途", Starring="徐峥", ShowAddress="XXX街影城", ShowTime=DateTime.Parse("2014-5-7 14:00:00"), TicketPrice=27.5M},new Movie(){ Id=9, MovieName="神探狄仁杰", Starring="未知", ShowAddress="观前街影城", ShowTime=DateTime.Parse("2014-5-8 14:00:00"), TicketPrice=28.5M},new Movie(){ Id=10, MovieName="里约大冒险2", Starring="未知", ShowAddress="观前街影城", ShowTime=DateTime.Parse("2014-5-9 14:00:00"), TicketPrice=29.5M},};IEnumerable<Movie> result;if (sortDir=="ASC"){result = (from ms in movies orderby GetMovieProperty(ms, sort) ascending select ms).Skip((page - 1) * rowsPerPage).Take(rowsPerPage);}else{result = (from ms in movies orderby GetMovieProperty(ms, sort) descending select ms).Skip((page - 1) * rowsPerPage).Take(rowsPerPage);}SelectMovies sm = new SelectMovies(){selectMovies = result.ToList(),totalCount=totalCount};return View(sm);}public object GetMovieProperty(object obj, string attrName){var property = obj.GetType().GetProperty(attrName);object value = property.GetValue(obj, null);return value;}
以上,关于服务器分页及排序记录到此。

MVC学习笔记八:WebGrid控件的高级使用相关推荐

  1. vs2010 学习Silverlight学习笔记(7):控件样式与模板

    概要: 终于知道Silverlight--App.xaml是干什么用的了,不仅可以用来封装样式(类似css),还可以制定控件模版...好强大的功能啊. 封装: 继续学习<一步一步学Silverl ...

  2. vb.net listview 删除选定行_VBA学习笔记59-1: listview控件

    学习资源:<Excel VBA从入门到进阶>第59集 by兰色幻想 本节学习Listview控件,它可以用多种视图方式显示项目的控件.由于其外形美观而且非常实用,所以使用频率很高. Lis ...

  3. JavaFX 学习笔记——窗口与控件

    前言 如今比较流行的桌面gui框架有WPF.WinForm.Qt.javafx等.其中WPF和WinForm目前还只能在运行Winsows上.Qt(widget)是一个很强大的跨平台C++框架(不只是 ...

  4. kendo treeview 修改节点显示值_VBA学习笔记60-1: Treeview控件

    学习资源:<Excel VBA从入门到进阶>第60集 by兰色幻想 本节讲Treeview控件. TreeView控件是以树形结构显示数据的控件.利用TreeView控件,可以设计出树形结 ...

  5. ASP.NET 学习笔记_01 广告控件的使用

    广告控件的使用: 广告文件是一个XML文件,广告文件中所有的标签属性被分析后放到adProperties字典中,用以属性编辑. ads.xml 1 <?xml version="1.0 ...

  6. Qt学习笔记之常用控件QlistWidget

    一.QListWidget Class The QListWidget class provides an item-based list widget. More... Header: #inclu ...

  7. Android开发学习笔记-自定义组合控件

    为了能让代码能够更多的复用,故使用组合控件.下面是我正在写的项目中用到的方法. 1.先写要组合的一些需要的控件,将其封装到一个布局xml布局文件中. <?xml version="1. ...

  8. LVGL v8学习笔记 | 06 - label控件的使用方法

    文章目录 一.label控件 1. 创建label对象 2. 设置label的文本 3. 获取label文本 4. label的大小 5. label的样式 6. label的事件 二.label控件 ...

  9. 【MFC】学习笔记:常用控件之组合框(Combo Box)

    01.目录 目录 01.目录 02.控件介绍 03.控件的消息通知函数 04.创建组合框控件及成员函数介绍 4.1 组合框的创建 4.2 CComboBox类的主要成员函数 05.应用实例 06.总结 ...

  10. Win32 学习笔记_列表控件(ListBox)

    ListBox控件 1. 创建控件 // 创建ListBox控件 HWND hListBox = CreateWindowEx(0, TEXT("ListBox"), NULL, ...

最新文章

  1. R语言使用vcd包的spine函数可视化spinogram图(spinogram图是被归一化的堆叠条形图、这样每个条形的高度一样、内部显示不同分布的比例)
  2. sap 给集团分配一个逻辑系统
  3. 多边形轮廓等比例缩放
  4. 关于Two pointers的个人理解
  5. 远程连接CentOS的MySQL报错:Can't connect to MySQL server on 'XXX' (13)
  6. ul+js模拟select
  7. aspx、ashx、asmx文件处理请求效率比较
  8. vitamio 缓冲一部分时,loading还没消失,直接点击播放,loading未能消失
  9. 荣耀20发布会花式官宣:4!-3!+2!伦敦见
  10. 【廖雪峰官方网站/Java教程】多线程(2)
  11. Redis 3.2.x版本 redis.conf 的配置文件参数详解
  12. windows上怎么用libnfc的库函数编程
  13. SpringBoot整合ureport2
  14. Java毕业设计-疫情防控系统
  15. 自动机器学习-H2O.ai
  16. 明源售楼系统技术解析 折扣管理(二)
  17. android型号的平板电脑,AUTOID Pad /Air-(win)/Air-(android)工业级平板电脑
  18. 运用jQuery实现一个简易轮播图
  19. 主数据管理(MDM)的一些概念
  20. 数据结构——栈和队列

热门文章

  1. 聚类:Python遗传算法
  2. ArcGIS10.2的详细安装过程和下载方法
  3. QT调用OpenCV
  4. Qt 环境下MAPX组件的编程
  5. java爬虫实例_Java爬虫完整实例源码
  6. SUMO与各类软件的联合仿真方法
  7. robocopy 备份_使用Robocopy复制、备份文件夹
  8. 书单 | 专为程序员而写的数学书
  9. MyBatis教程(看这一篇就够了)
  10. 二类高层建筑中的电子计算机,高层建筑结构计算机计算原理及结果简析