MVC学习笔记八:WebGrid控件的高级使用
来源:互联网 发布:淘宝提交多个订单 编辑:程序博客网 时间:2024/05/17 05:06
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 表) tmpWHERE 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; }
以上,关于服务器分页及排序记录到此。
0 0
- MVC学习笔记八:WebGrid控件的高级使用
- MVC学习笔记三:WebGrid控件的简单使用
- JS开发的WebGrid控件
- MVC入门教程八[MvcPager分页控件的使用]
- android学习八(ListView的高级使用)
- Spring学习笔记之Spring MVC的高级技术
- javascript高级开发学习笔记八
- MVC入门学习笔记(八)
- Spring MVC 学习笔记 八 文件上传
- [学习笔记]基于注解的spring3.0.x MVC学习笔记(八)
- [学习笔记]基于注解的spring3.0.x MVC学习笔记(八)
- webgrid的使用:(二)、动态的添加webcombo到webgrid上的操作
- 自定义控件学习笔记(八)
- (八) Select控件的使用
- webgrid 用法 asp.net mvc
- C# 学习笔记五 高级控件
- Android 学习笔记9:高级控件
- MVC学习八:MVC3的远程验证
- Linux上JDK、Eclipse的安装
- 网络视频监控P2P解决方案
- Qt 游戏之路(一) 场景搭建 和 战车移动、地图拉伸
- 简单Struts2实例(入门级)
- 1006. Sign In and Sign Out
- MVC学习笔记八:WebGrid控件的高级使用
- 002_005 Python 计算一个文件中有多少行即读取文件行数
- PAT-1075. PAT Judge
- C#访问MySQL的驱动程序下载
- count,count_if
- linux进程管理(1)---进程描述符
- linux和windows的文本文件 换行格式转换
- Refptr and PassRefPtr basic
- 《C++编程思想II》第一章-异常处理