ASP.NET MVC分页控件的实现


  本文标签:ASP.NET MVC分页控件

  需求及模拟代码

  需求,假设我们有个列表,有分页功能,我们可能需要一个页码列表,如

  我们可能需要一个页码列表  

  我们模拟写一下Action:

  1. public ActionResult Index(int? p)  
  2. {  
  3.     if (!p.HasValue) p = 1;//如果未对p传值就是第1页  
  4.     var list = new List< int>();//生成一个模拟列表  
  5.     for (var i = 0; i <  10;i++ )  
  6.     {  
  7.         list.Add(p.Value);//是第几页就向中填充几个这个页码的数  
  8.     }  
  9.     return View(list);//强型传递给View  

  View中我写以下显示方式:

  1. < %@ Page Language="C#" MasterPageFile="'/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage< List< int>>" %>  
  2.     
  3.  < asp:Content ID="indexTitle" ContentPlaceHolderID="TitleContent" runat="server">  
  4.      Pager for List  
  5.  < /asp:Content>  
  6.     
  7.  < asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">  
  8.      < div>  
  9.          < ul>  
  10.             < %foreach (int i in Model){//显示这个列表%>  
  11.             < li>< %=i %>< /li>  
  12.             < %} %>  
  13.         < /ul>  
  14.     < /div>  
  15.     < !--将在这里显示分页的部分-->  
  16.    < /asp:Content> 

  下面是运行后的结果:

  ASP.NET MVC分页控件:第一页URL类似/Home/Index?p=1

  第一页URL类似/Home/Index?p=1  

  ASP.NET MVC分页控件:第二页URL类似/Home/Index?p=2

  第二页URL类似/Home/Index?p=2

  其它页面以此类推

  ASP.NET MVC分页控件:最简单的解决方案

  我想最简单无非就是直接写链接,当然也要考虑更换Routing规则的问题,所以我们可以最简单如下来写: 

  1. < %  
  2.              int p = 1;  
  3.              int.TryParse(Request.QueryString["p"], out p);  
  4.    %>  
  5.    < div>  
  6.    < %=Html.ActionLink("上一页""Index"new { p= p-1})%>  
  7.    < strong>当前页:< %=p %>< /strong>  
  8.    < %=Html.ActionLink("下一页""Index"new { p= p+1})%>  
  9.    < /div>  

  这样就可以得到如果下的分页样式

  这样就可以得到如果下的分页样式  

  当然,也可以根据这个来写1,2,3,4,5页的链接,而不写“上一页”或“下一页”

  但是这种方法有个问题,就是使用Html.ActionLink的时候要用字符串来指定Action和Controller  。下面我们来改换另一种方法来实现

  使用RouteLink来实现

  我们使用Html.RouteLink就可以实现不与Action或Controller的名称相耦合,例如:

  1. < %for (int i = 1; i <  10; i++)  
  2.     {  
  3.         ViewContext.RouteData.Values["p"] = i;//设置页码  
  4.         Writer.Write(  
  5.            Html.RouteLink(i.ToString(), ViewContext.RouteData.Values)  
  6.             );//显示设置页面后的链接  
  7.         Writer.Write(" ");//连接后显示个空格,好看点  
  8.         
  9.     }%> 

  这个列表,我们就可以显示为

  这个列表,我们就可以显示为 

  完善这个Pager并封装成一个Helper

  上面列出了Pager,但是有几个问题

  1.没有上下页

  2.没有指定当前页的特殊显示

  3.每次调用时都要写一次

  4.如果QueryString有其它参数时无法处理

  那我们下面来完善这个Pager

  并将之封装成一个Helper 

  1. using System;  
  2.   using System.Collections.Generic;  
  3.   using System.Linq;  
  4.   using System.Web;  
  5.   using System.Web.Mvc;  
  6.   using System.Web.Routing;  
  7.   using System.Text;  
  8.   using System.Web.Mvc.Html;  
  9.     
  10.  namespace MvcApplication2.Helpers  
  11.  {  
  12.      public static class PagerExtensions  
  13.      {  
  14.          /**//// < summary>    
  15.          /// 分页Pager显示    
  16.          /// < /summary>     
  17.          /// < param name="html">< /param>    
  18.          /// < param name="currentPageStr">标识当前页码的QueryStringKey< /param>     
  19.          /// < param name="pageSize">每页显示< /param>    
  20.          /// < param name="totalCount">总数据量< /param>    
  21.          /// < returns>< /returns>   
  22.          public static string Pager(this HtmlHelper html, string currentPageStr, int pageSize, int totalCount)  
  23.          {  
  24.             var queryString = html.ViewContext.HttpContext.Request.QueryString;  
  25.              int currentPage = 1; //当前页    
  26.              var totalPages = Math.Max((totalCount + pageSize - 1) / pageSize, 1); //总页数    
  27.              var dict = new System.Web.Routing.RouteValueDictionary(html.ViewContext.RouteData.Values);  
  28.              var output = new System.Text.StringBuilder();  
  29.              if (!string.IsNullOrEmpty(queryString[currentPageStr]))  
  30.              {  
  31.                  //与相应的QueryString绑定   
  32.                  foreach (string key in queryString.Keys)  
  33.                      if (queryString[key] != null && !string.IsNullOrEmpty(key))  
  34.                         dict[key] = queryString[key];  
  35.                  int.TryParse(queryString[currentPageStr], out currentPage);  
  36.              }  
  37.              else 
  38.              {  
  39.                  //获取 ~/Page/{page number} 的页号参数  
  40.                  int.TryParse(dict[currentPageStr].ToString(), out currentPage);  
  41.              }  
  42.              if (currentPage < = 0) currentPage = 1;  
  43.              if (totalPages > 1)  
  44.              {  
  45.                  if (currentPage != 1)  
  46.                  {  
  47.                      //处理首页连接    
  48.                      dict[currentPageStr] = 1;  
  49.                      output.AppendFormat("{0} ", html.RouteLink("首页", dict));  
  50.                  }  
  51.                  if (currentPage > 1)  
  52.                  {  
  53.                      //处理上一页的连接    
  54.                      dict[currentPageStr] = currentPage - 1;  
  55.                      output.Append(html.RouteLink("上一页", dict));  
  56.                 }  
  57.                  else 
  58.                  {  
  59.                      output.Append("上一页");  
  60.                  }  
  61.                  output.Append(" ");  
  62.                  int currint = 5;  
  63.                  for (int i = 0; i < = 10; i++)  
  64.                  {  
  65.                      //一共最多显示10个页码,前面5个,后面5个    
  66.                      if ((currentPage + i - currint) >= 1 && (currentPage + i - currint) < = totalPages)  
  67.                          if (currint == i)  
  68.                          {  
  69.                              //当前页处理    
  70.                              output.Append(string.Format("[{0}]", currentPage));  
  71.                          }  
  72.                          else 
  73.                          {  
  74.                              //一般页处理   
  75.                              dict[currentPageStr] = currentPage + i - currint;  
  76.                              output.Append(html.RouteLink((currentPage + i - currint).ToString(), dict));  
  77.                          }  
  78.                      output.Append(" ");  
  79.                  }  
  80.                  if (currentPage <  totalPages)  
  81.                  {  
  82.                      //处理下一页的链接   
  83.                      dict[currentPageStr] = currentPage + 1;  
  84.                      output.Append(html.RouteLink("下一页", dict));  
  85.                  }  
  86.                  else 
  87.                  {  
  88.                      output.Append("下一页");  
  89.                  }  
  90.                  output.Append(" ");  
  91.                  if (currentPage != totalPages)  
  92.                  {  
  93.                      dict[currentPageStr] = totalPages;  
  94.                      output.Append(html.RouteLink("末页", dict));  
  95.                  }  
  96.                 output.Append(" ");  
  97.              }  
  98.              output.AppendFormat("{0} / {1}", currentPage, totalPages);//这个统计加不加都行   
  99.              return output.ToString();  
  100.         }  
  101.     } 

  添加Controller代码:

  1. public ActionResult Index(int? page)  
  2.         {  
  3.             if (page == null)  
  4.                 page = 1;  
  5.             return View();  
  6.         }  

  aspx页面调用:

  1. < %=Html.Pager("page", 10, 10020)%> 

  

  效果

  效果 

  这回我们算是解决了这个问题,ASP.NET MVC分页控件成功构建  。