MVC项目中的分页实现例子

在开发项目中,写了一个分页实现的例子,现在把源代码贴上,以供以后写代码时参考

在列表的头部,有如下显示,

   这个代表一个页面显示10条记录,总共22条记录。

这个是页面底部的显示

那么如何来显示这个分页效果,如何来写一个泛型的通用的分页类实现分页效果呢

 第1个类 Paging.cs

这个类包括分页需要的一些变量,包括 页面数PageCount, 上面图片中Previous,Next是否显示, 以及Previous 和 Next对应的链接URL, 以及组成URL的各部分

using System;
using System.Collection.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;

public class Paging
{
    public string PrependStr = string.Empty;
    public string UrlPart;
    public string NextHrefUrl = "";
    public string PrevHrefUrl = "";
    public bool IsPreviousVisible = false;
    public bool IsNextVisible = false;

    private int _pageCount;
    private string _summary;

    public int[] Numbers {get; set;}
    public int PageSize {get; set;}
    
   
    public int PageNo
    {
       get
       {
          int pageNo = 1;
          if(HttpContext.Current.Request["page"] != null && !String.IsNullOrEmpty(HttpContext.Current.Request["page"]))
           {
              Int32.TryParse(HttpContext.Current.Request["page"], out pageNo);
           }
           return pageNo;

         }

 
      }


     public void BindPaging(string urlPart, int recordCount, int pageSize, string prependStr, string summary)
    {

        _pageCount = (int)Math.Ceiling((decimal)recordCount / pageSize);
        UrlPart = urlPart.Split('?')[0];
        _summary = summary;
        PrependStr = prependStr;

        Numbers = new int[_pageCount];
        for(int i = 1; i <= _pageCount; i++)
             Numbers[i-1] = i;

       PrepagePaging();
       
     }

     protected void PreparePaging()
     {
           if(PageNo == 1)
                IsPreviousVisible = false;
          
           if (PageNo == 1 && _pageCount == 1)
            {
                IsPreviousVisible = false;
                IsNextVisible = false;

            }
            else if (PageNo == 1 && PageNo < _pageCount)
            {
                IsPreviousVisible = false;
                IsNextVisible = true;
                NextHrefUrl = UrlPart + "?page=" + (PageNo + 1).ToString() + PrependStr;
            }
            else if (PageNo > 1 && PageNo < _pageCount)
            {
                IsPreviousVisible = true;
                PrevHrefUrl = UrlPart + "?page=" + (PageNo - 1).ToString() + PrependStr;
                IsNextVisible = true;
                NextHrefUrl = UrlPart + "?page=" + (PageNo + 1).ToString() + PrependStr;
            }
            else if (PageNo == _pageCount)
            {
                IsPreviousVisible = true;
                PrevHrefUrl = UrlPart + "?page=" + (PageNo - 1).ToString() + PrependStr;
                IsNextVisible = false;
            } 
          
     }

 
}
 

 上面这个类是分页需要的类,我们当然还需要一个类,来实现分页中的实际页面,也就是PagedResult, 但是因为我们并不知道页面中的具体内容,我们是要做一个通用的例子,所以,使用泛型来实现

 第2个类 PagedResult.cs

我们来看看这个类, 我们先定义一个泛型接口 IPagedResult<T> 

public interface IPagedResult<T>
{
     ICollection<T> Result {get;}
     
     int Total {get;}
     int CurrentPage {get; set;}
     int PageCount {get; set;}
     int PageSize {get; set;}
     int RowCount {get; set;}
     
     bool IsEmpty {get;}
   
     void Add(T entity);

     string GetCurrentPageRangeString();



}

接下来我们再定义一个泛型类PagedResult<T>,来继承这个泛型接口

public class PagedResult<T> : IPagedResult<T>
{
       private readonly Collection<T> _result;
       private readonly int _total;

       //依赖注入 构造函数
       public PagedResult(IEnumerable<T> result, int total)
       {
                 _result = new Collection<T>(new List<T>(result)); // 这里也是一个小知识点,可以通过new List(IEnumerable) 把IEnumerable类型转为List类型
                 _total = total;

               
        }

        public PagedResult() : this(new List<T>(),0)
        {
                
         }

        public int CurrentPage {get; set;}
        
        public bool IsEmpty
        {
            
             get
             {
                    return _result.Count == 0;
              }            
        }
      
         public int PageCount {get; set;}
         public int PageSize {get; set;}

         public ICollection<T> Result
         {
                  get
                  {
                        return _result;
                   }
         }
    
        public int RowCount {get; set;}

        public int Total
        {
            get
            {
                  return _total;
            }
        }
        
        public void Add(T entity)
        {
                _result.Add(entity);
        }

        public string GetCurrentPageRangeText()
        { 
             CurrentPage = CurrentPage == 0 ? 1: CurrentPage;
             var start = PageSize * (CurrentPage - 1) + 1;
             var end = CurrentPage * PageSize <= Total ? start + PageSize -1 : Total;
              if(Total == 0)
                 return "No results found";
              
              string resultsOf = "results of";
              string showing = "Showing";
              
              
              return string.Format("{0} {1} - {2} {3} {4}", showing, start, end, resultsOf, Total);

             
          
        }
        
   
}

 我们还需要一个类,是根据类的结果列表来获取它的页结果列表PagedResult, 这是一个帮助类. 我们给它取名为PaginationHelper.cs

public static class PaginationHelper
{
     
      public static int TotalPage(int total, int rowPerPage)
      {
            if((total == 0) || (rowPerPage == 0))
            {
                  return 1;
            }
           
            if((total % rowPerPage) == 0)
            {
                   return total / rowPerPage;
                   
            }
             
            double result = Convert.ToDouble(total / rowPerPage);
            
            result = Math.Ceiling(result);
          
            return Convert.ToInt32(result) + 1;



    
      }


     public static int StartIndex(int? page, int rowPerPage)
     {
         return (page.HasValue && (page.Value > 1)) ? ((page.Value -1) * rowPerPage) : 0;

     }

     public static PagedResult<T> GetPagedResultSet<T>(IEnumerable<T> resultSet, int pageSize, int? currentPage)
     {
             if(resultSet == null)
                  return new PagedResult<T>();              
             var result = new List<T>(resultSet);  //这个是把IEnumerable转换为List的方法
             var resultCount = result.Count;
              
             var startIndex = StartIndex(currentPage, pageSize);
             var results = result.Skip(startIndex).Take(pageSize); // 这里放的是当前这个页面的结果列表,因为我们在View中需要列出当前那页的结果列表
              var pageTotals = TotalPage(resultCount,pageSize);

               if(currentPage.HasValue && currentPage > pageTotals)             
                            currentPage = null;

                var pageResultSet = new PagedResult<T>(results,resultCount)
                {
                   CurrentPage = currentPage.HasValue ? currentPage.Value : 1,
                   PageCount = pageTotals,
                   PageSize = pageSize


                 };

                 return pagedResultSet;
                   
              

     }

public static PagedResult<T> GetPagedResult<T>(Func<IEnumerable<T>> func, int pageSize, int? currentPageIndex) where T : class
{
    return GetPagedResultSet(func(), pageSize, currentPageIndex);

}

 现在我们开始写这个View

    

写这个图显示的View, 它用的Model 就是上面的Paging.cs, 我们可以看到,这个类Paging.cs没有关注分页的内容是什么,也就是它拥有完全的通用性,无论分页中的内容具体是什么,都可以使用这个来实现这个图示例的分页,那我们现在来看看这个View是怎么写的

Paging.cshtml

@inherits UmbracoViewPage<Paging>


@if (Model.Numbers.Length > 1)
{

    <div class="row">
        <div class="col-md-6">
            <div class="pagination-page">
                <ul>
                    @if (Model.IsPreviousVisible)
                    {
                        <li>
                            <a href="@Model.PrevHref">Previous</a>
                        </li>
                    }
                    @foreach (var number in Model.Numbers)
                    {
                    var urlHref = Model.UrlPart + "?page=" + (number).ToString() + Model.PrependStr;
                        <li class="@(number == Model.PageNo ? "active" : string.Empty)">
                            <a href="@urlHref">@number</a>
                        </li>
                    }
                    @if (Model.IsNextVisible)
                    {
                        <li>
                            <a href="@Model.NextHref">Next</a>
                        </li>
                    }
                </ul>
            </div>
        </div>
    </div>
}

这里面还有一些css 我就不贴在这里了,CSS及格式可以自己设置调整

接下来我们就来看看分页内容的实现,也就是说每一页中的内容的实现

我们举个例子,这个列表是News的列表,每页显示10条News,每一条News上的title上是一个链接,点击这个链接会打开一个新的页面(有这个news的URL去链接到另一个页面)来显示这个news的全部内容

显示每页News内容的页面,所使用的Model是NewsSearchResult, 具体如下

NewsSearchResult.cs

public class NewsSearchResult
{

     public NewsSearchResult()
     {

      }

      public int? PageNo {get; set;}

      public IPagedResult<NewsResult> NewsResults {get; set;}

      public Paging Paging {get; set;}

}

可以看到,它这里用到了我们上面定义的Paging类,已经接口IPagedResult<T>, 里面又有一个类NewsResult, 定义的是每一个News所包含的一些基本属性(title, url等), 我们来看看它的定义

NewsResult.cs

public class NewsResult
{

     public string NewsTitle {get; set;}
     
     public string NewsDesc {get; set;}
    
     public string NewsDate {get; set;}
    
     public string PageUrl {get; set;}
     
}

 定义好了model后,我们来看看MVC中的Controller的实现,我们取名为SearchController.cs

SearchController.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

public class SearchController : Controller
{
      
     public ActionResult Render()
     {
        return View("NewsListSearch.cshtml", BuildInitialModel());
    
      }

      public NewsSearchResult BuildInitialModel()
      {
         NewsSearchResult model = new NewsSearchResult();
         model.PageNo = !string.IsNullOrEmpty(Request["page"]) ? Int32.Parse(Request["page"]) : 0;
         List<NewsResult> newsResults = GetAllNewsList();
         Paging paging = new Paging();
         IPagedResult<NewsResult> pagedResultSet = null;
         pagedResultSet = PaginationHelper.GetPagedResultSet(newsResults,10,paging.PageNo); //每页面显示10条结果
         paging.BindPaging(Request.RawUrl, pagedResultSet.Total,10,string.Empty,string.Empty);
         model.Paging = paging;
         model.NewsResults = pagedResultSet;
         return model;
      
      }     


       private List<NewsResult> GetAllNewsList()
       {
         List<NewsResult> allNewsResults = new List<NewsResult>{
                  
          new NewsResult {NewsTitle = "News 1", NewsDesc = "This is the description for News 1", NewsDate = "2017-01", PageUrl = "www.ournews.com/list/news1"},
          new NewsResult {NewsTitle = "News 2", NewsDesc = "This is the description for News 2", NewsDate = "2017-02", PageUrl = "www.ournews.com/list/news2"},
          new NewsResult {NewsTitle = "News 3", NewsDesc = "This is the description for News 3", NewsDate = "2017-03", PageUrl = "www.ournews.com/list/news3"},
          new NewsResult {NewsTitle = "News 4", NewsDesc = "This is the description for News 4", NewsDate = "2017-04", PageUrl = "www.ournews.com/list/news4"},
          new NewsResult {NewsTitle = "News 5", NewsDesc = "This is the description for News 5", NewsDate = "2017-05", PageUrl = "www.ournews.com/list/news5"},
          new NewsResult {NewsTitle = "News 6", NewsDesc = "This is the description for News 6", NewsDate = "2017-06", PageUrl = "www.ournews.com/list/news6"},
          new NewsResult {NewsTitle = "News 7", NewsDesc = "This is the description for News 7", NewsDate = "2017-07", PageUrl = "www.ournews.com/list/news7"},
          new NewsResult {NewsTitle = "News 8", NewsDesc = "This is the description for News 8", NewsDate = "2017-08", PageUrl = "www.ournews.com/list/news8"},
          new NewsResult {NewsTitle = "News 9", NewsDesc = "This is the description for News 9", NewsDate = "2017-09", PageUrl = "www.ournews.com/list/news9"},
          new NewsResult {NewsTitle = "News 10", NewsDesc = "This is the description for News 10", NewsDate = "2017-10", PageUrl = "www.ournews.com/list/news10"},
          new NewsResult {NewsTitle = "News 11", NewsDesc = "This is the description for News 11", NewsDate = "2017-11", PageUrl = "www.ournews.com/list/news11"},
          new NewsResult {NewsTitle = "News 12", NewsDesc = "This is the description for News 12", NewsDate = "2017-12", PageUrl = "www.ournews.com/list/news12"},
          new NewsResult {NewsTitle = "News 13", NewsDesc = "This is the description for News 13", NewsDate = "2018-01", PageUrl = "www.ournews.com/list/news13"},
          new NewsResult {NewsTitle = "News 14", NewsDesc = "This is the description for News 14", NewsDate = "2018-02", PageUrl = "www.ournews.com/list/news14"},
          new NewsResult {NewsTitle = "News 15", NewsDesc = "This is the description for News 15", NewsDate = "2018-03", PageUrl = "www.ournews.com/list/news15"},
          new NewsResult {NewsTitle = "News 16", NewsDesc = "This is the description for News 16", NewsDate = "2018-04", PageUrl = "www.ournews.com/list/news16"},
          new NewsResult {NewsTitle = "News 17", NewsDesc = "This is the description for News 17", NewsDate = "2018-05", PageUrl = "www.ournews.com/list/news17"},
          new NewsResult {NewsTitle = "News 18", NewsDesc = "This is the description for News 18", NewsDate = "2018-06", PageUrl = "www.ournews.com/list/news18"},
          new NewsResult {NewsTitle = "News 19", NewsDesc = "This is the description for News 19", NewsDate = "2018-07", PageUrl = "www.ournews.com/list/news19"},
          new NewsResult {NewsTitle = "News 20", NewsDesc = "This is the description for News 20", NewsDate = "2018-08", PageUrl = "www.ournews.com/list/news20"},
          new NewsResult {NewsTitle = "News 21", NewsDesc = "This is the description for News 21", NewsDate = "2018-09", PageUrl = "www.ournews.com/list/news21"},
          new NewsResult {NewsTitle = "News 22", NewsDesc = "This is the description for News 22", NewsDate = "2018-10", PageUrl = "www.ournews.com/list/news22"},
          new NewsResult {NewsTitle = "News 23", NewsDesc = "This is the description for News 23", NewsDate = "2018-11", PageUrl = "www.ournews.com/list/news23"},
          new NewsResult {NewsTitle = "News 24", NewsDesc = "This is the description for News 24", NewsDate = "2018-12", PageUrl = "www.ournews.com/list/news24"}
      
              }
              
        }
}

 现在我们来看看这个展示结果页面的View, 也就是每一个页面实际显示的View  ===>   NewsList.cshtml

@inherits UmbracoViewPage<NewsSearchResult>
<div class="col-md-12">
    <div class="support-item" style="padding-bottom:0px">
        @foreach (var newsResult in Model.NewsResults.Result)
        {
              <a href="@newsResult.PageUrl">@newsResult.NewsTitle</a>
                      
                        <div>
                            <p class="small">@newsResult.NewsDesc</p>
                            <a href="@newsResult.PageUrl">
                                <span class="small">Read News

                                ›</span>
                            </a>
                        </div>
                    </div>
                </div>
   
        }
    </div>
</div>

这上面的 Model.NewsResults.Result 里面是当前页面的那个10条News结果

最后,我们来看看页面顶部的 显示当前News记录顺序的View, 就是显示如下图示的View

  

我们给这个View取名为ShowingDesc.cshtml, 内容如下

@inherits UmbracoViewPage<NewsSearchResult>

<div class="col-md-6">
    @if (Model.NewsResults.Total > 0)
    {
        <p class="pagination-result" style="text-align: left;">
            <strong> @Model.NewsResults.GetCurrentPageRangeString() </strong>
           
        </p>
    }

</div>

到目前为止,页面的3部分都有了,分别是 ShowingDesc.cshtml, NewsList.cshtml,Paging.cshtml  我们把它们组成最后的显示页面 NewsListSearch.cshtml

@inherits Umbraco.Web.Mvc.UmbracoViewPage<NewsSearchResult>

<div class="col-md-12">
    
    @Html.Partial("ShowingDesc.cshtml", Model)
    <hr />
</div>

@Html.Partial("NewsList.cshtml", Model)
<div class="col-md-12">
    @Html.Partial("Paging.cshtml", Model.Paging)
</div>
原文地址:https://www.cnblogs.com/wphl-27/p/9429448.html