| 
 | 
 
WebGrid 给我们开发人员提供了很好的分页和排序功能,优点很明显。但看完下面的例子后会发现一个问题:不管获取每一页都会去取出所有的数据,假如说其中有100W条数据,在用foreach去循环的话,就会造成crash,所以需要我们更好地派生WebGrid类。 
创建派生 WebGrid其中用...代替的大家可以通过F12到WebGrid class中查看具体参数,比较多,所以这边就用...代替了-  public class WebGrid<T> : WebGrid
 
 -   {
 
 -     public WebGrid(
 
 -       IEnumerable<T> source = null,
 
 -       ...
 
 -           parameter list omitted for brevity)
 
 -     : base(
 
 -       source.SafeCast<object>(), 
 
 -       ...
 
 -           parameter list omitted for brevity)
 
 -     { }
 
 -   public WebGridColumn Column(
 
 -               string columnName = null, 
 
 -               string header = null, 
 
 -               Func<T, object> format = null, 
 
 -               string style = null, 
 
 -               bool canSort = true)
 
 -     {
 
 -       Func<dynamic, object> wrappedFormat = null;
 
 -       if (format != null)
 
 -       {
 
 -         wrappedFormat = o => format((T)o.Value);
 
 -       }
 
 -       WebGridColumn column = base.Column(
 
 -                     columnName, header, 
 
 -                     wrappedFormat, style, canSort);
 
 -       return column;
 
 -     }
 
 -     public WebGrid<T> Bind(
 
 -             IEnumerable<T> source, 
 
 -             IEnumerable<string> columnNames = null, 
 
 -             bool autoSortAndPage = true, 
 
 -             int rowCount = -1)
 
 -     {
 
 -       base.Bind(
 
 -            source.SafeCast<object>(), 
 
 -            columnNames, 
 
 -            autoSortAndPage, 
 
 -            rowCount);
 
 -       return this;
 
 -     }
 
 -   }
 
 -  
 
 -   public static class WebGridExtensions
 
 -   {
 
 -     public static WebGrid<T> Grid<T>(
 
 -              this HtmlHelper htmlHelper,
 
 -              ...
 
 -           parameter list omitted for brevity)
 
 -     {
 
 -       return new WebGrid<T>(
 
 -         source, 
 
 -         ...
 
 -           parameter list omitted for brevity);
 
 -     }
 
 -   }
 
  复制代码 这样做有什么好处呢?          通过实现这个新的 WebGrid<T>,我添加了一个新的 Column 方法,该方法以 Func<T, object> 作为 format 参数,这意味着在调用扩展方法时不必再进行转换。          
                  通过这种 Grid 扩展方法,您能够利用编译器针对范型参数的类型推断功能。          因此,本例中我们只需要编写 Html.Grid(Model),而不必编写新的 WebGrid<Object>(Model)。          无论采用哪种方式,返回的类型都是 WebGrid<Object>。例如:-     public class PagedObjsModel
 
 -     {
 
 -         /// <summary>
 
 -         /// Model
 
 -         /// </summary>
 
 -         public IEnumerable<object> ModelValue { get; set; }
 
  
-         /// <summary>
 
 -         /// 每页个数
 
 -         /// </summary>
 
 -         public int PageSize { get; set; }
 
  
-         /// <summary>
 
 -         /// 页码
 
 -         /// </summary>
 
 -         public int PageNumber { get; set; }
 
  
-         /// <summary>
 
 -         /// 总数
 
 -         /// </summary>
 
 -         public int TotalRows { get; set; }
 
 -     }
 
  复制代码 实现 WebGrid 服务器端分页的第一步是限制从数据源检索的数据量。          为此,需要知道请求的是哪一页数据,以便检索正确的数据页。          WebGrid 在呈现分页链接时,会重复使用页面的 URL,并在页码中附加一个查询字符串参数,例如 http://localhost:27617/Product/DefaultPagingAndSorting?page=3(该查询字符串参数的名称可通过帮助程序参数进行配置,这在支持同一页面中多个网格的分页时非常有用)。          也就是说,您可以在自己的操作方法中采用一个名为 page 的参数,然后使用查询字符串值填充该参数。         
                  如果只是通过修改现有代码向 WebGrid 传递单页数据,则 WebGrid 只会看到单页数据。          由于它不知道还有别的页面,因而不再呈现分页器控件。          幸运的是,WebGrid 还有一种名为 Bind 的方法,可用来指定数据。          Bind 不仅能够接受数据,而且有一个表示总行数的参数,从而据此计算页数。          为了使用此方法,需要更新 List 操作以检索更多信息并将其传入视图,如图 7 所示         
Controll代码如下:- public ActionResult List(int page = 1)
 
 - {
 
 -   const int pageSize = 5;
 
 -  
 
 -   int totalRecords;
 
 -   IEnumerable<Product> products = productService.GetProducts(
 
 -     out totalRecords, pageSize:pageSize, pageIndex:page-1);
 
 -             
 
 -   PagedProductsModel model = new PagedProductsModel
 
 -                                  {
 
 -                                    PageSize= pageSize,
 
 -                                    PageNumber = page,
 
 -                                    Products = products,
 
 -                                    TotalRows = totalRecords
 
 -                                  };
 
 -   return View(model);
 
 - }
 
  复制代码 利用这些附加信息,即可更新视图以使用 WebGrid 的 Bind 方法。          通过调用 Bind 可提供要呈现的数据和总行数,并将 autoSortAndPage 参数设置为 false。          autoSortAndPage 参数告知 WebGrid 不需要应用分页,因为这由 List 方法负责。          对此可用下面代码说明-       <div>
 
 - @{
 
 -   var grid = new WebGrid<Product>(null, rowsPerPage: Model.PageSize, 
 
 -     defaultSort:"Name");
 
 -   grid.Bind(Model.Products, rowCount: Model.TotalRows, autoSortAndPage: false);
 
 - }
 
 - @grid.GetHtml(columns: grid.Columns(
 
 -  grid.Column("Name", format: @<text>@Html.ActionLink(item.Name, 
 
 -    "Details", "Product", new { id = item.ProductId }, null)</text>),
 
 -   grid.Column("ListPrice", header: "List Price", 
 
 -     format: @<text>@item.ListPrice.ToString("0.00")</text>)
 
 -   )
 
 -  )
 
 -  
 
 - </div>
 
  复制代码 当然在上述代码中,您也可以指定一些样式:可以先将columns值赋值好,然后通过下面代码填充GetHtml- @grid.GetHtml(
 
 -                 tableStyle: "ContactTB",
 
 -                 headerStyle: "ContactHD",
 
 -                 rowStyle: "Content",
 
 -                 firstText: "首页",
 
 -                 previousText: "上一页",
 
 -                 nextText: "下一页",
 
 -                 lastText: "末页",
 
 -                 mode: WebGridPagerModes.All, //这段代码就是控制分页显示的样式,选择ALL,都兼容。
 
 -                 columns: gridColumns
 
  复制代码 Done, 这样分页就不会每次取出所有的数据了,而只会每次取出每页的数据。 
由于关闭了 autoSortAndPage,排序功能遭到破坏。          WebGrid 利用查询字符串参数来传递排序列和方向,但我们已命令它不执行排序,所以WebGrid的方法介绍三介绍排序功能! 
 
 
 
 |   
 
 
 
 |