Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>I forget where it came from. Perhaps someone could post the link as a comment here.</p> <p>I think this is code complete.</p> <p>I have this as a project; </p> <p>MvcPaging;</p> <p><strong>IPagedList</strong></p> <pre><code>using System.Collections.Generic; namespace MvcPaging { public interface IPagedList&lt;T&gt; : IList&lt;T&gt; { int PageCount { get; } int TotalItemCount { get; } int PageIndex { get; } int PageNumber { get; } int PageSize { get; } bool HasPreviousPage { get; } bool HasNextPage { get; } bool IsFirstPage { get; } bool IsLastPage { get; } } } </code></pre> <p><strong>PagedList</strong></p> <pre><code>using System; using System.Collections.Generic; using System.Linq; using MvcPaging; namespace MvcPaging { public class PagedList&lt;T&gt; : List&lt;T&gt;, IPagedList&lt;T&gt; { public PagedList(IEnumerable&lt;T&gt; source, int index, int pageSize) : this(source, index, pageSize, null) { } public PagedList(IEnumerable&lt;T&gt; source, int index, int pageSize, int? totalCount) { Initialize(source.AsQueryable(), index, pageSize, totalCount); } public PagedList(IQueryable&lt;T&gt; source, int index, int pageSize) : this(source, index, pageSize, null) { } public PagedList(IQueryable&lt;T&gt; source, int index, int pageSize, int? totalCount) { Initialize(source, index, pageSize, totalCount); } #region IPagedList Members public int PageCount { get; private set; } public int TotalItemCount { get; private set; } public int PageIndex { get; private set; } public int PageNumber { get { return PageIndex + 1; } } public int PageSize { get; private set; } public bool HasPreviousPage { get; private set; } public bool HasNextPage { get; private set; } public bool IsFirstPage { get; private set; } public bool IsLastPage { get; private set; } #endregion protected void Initialize(IQueryable&lt;T&gt; source, int index, int pageSize, int? totalCount) { //### argument checking if (index &lt; 0) { throw new ArgumentOutOfRangeException("PageIndex cannot be below 0."); } if (pageSize &lt; 1) { throw new ArgumentOutOfRangeException("PageSize cannot be less than 1."); } //### set source to blank list if source is null to prevent exceptions if (source == null) { source = new List&lt;T&gt;().AsQueryable(); } //### set properties if (!totalCount.HasValue) { TotalItemCount = source.Count(); } PageSize = pageSize; PageIndex = index; if (TotalItemCount &gt; 0) { PageCount = (int)Math.Ceiling(TotalItemCount / (double)PageSize); } else { PageCount = 0; } HasPreviousPage = (PageIndex &gt; 0); HasNextPage = (PageIndex &lt; (PageCount - 1)); IsFirstPage = (PageIndex &lt;= 0); IsLastPage = (PageIndex &gt;= (PageCount - 1)); //### add items to internal list if (TotalItemCount &gt; 0) { AddRange(source.Skip((index) * pageSize).Take(pageSize).ToList()); } } } } </code></pre> <p><strong>Pager</strong></p> <pre><code>using System; using System.Text; using System.Web.Mvc; using System.Web.Routing; namespace MvcPaging { public class Pager { private ViewContext viewContext; private readonly int pageSize; private readonly int currentPage; private readonly int totalItemCount; private readonly RouteValueDictionary linkWithoutPageValuesDictionary; public Pager(ViewContext viewContext, int pageSize, int currentPage, int totalItemCount, RouteValueDictionary valuesDictionary) { this.viewContext = viewContext; this.pageSize = pageSize; this.currentPage = currentPage; this.totalItemCount = totalItemCount; this.linkWithoutPageValuesDictionary = valuesDictionary; } public string RenderHtml() { int pageCount = (int)Math.Ceiling(this.totalItemCount / (double)this.pageSize); int nrOfPagesToDisplay = 10; var sb = new StringBuilder(); // Previous if (this.currentPage &gt; 1) { sb.Append(GeneratePageLink("Previous", this.currentPage - 1)); } else { sb.Append("&lt;span class=\"disabled\"&gt;Previous&lt;/span&gt;"); } int start = 1; int end = pageCount; if (pageCount &gt; nrOfPagesToDisplay) { int middle = (int)Math.Ceiling(nrOfPagesToDisplay / 2d) - 1; int below = (this.currentPage - middle); int above = (this.currentPage + middle); if (below &lt; 4) { above = nrOfPagesToDisplay; below = 1; } else if (above &gt; (pageCount - 4)) { above = pageCount; below = (pageCount - nrOfPagesToDisplay); } start = below; end = above; } if (start &gt; 3) { sb.Append(GeneratePageLink("1", 1)); sb.Append(GeneratePageLink("2", 2)); sb.Append("..."); } for (int i = start; i &lt;= end; i++) { if (i == this.currentPage) { sb.AppendFormat("&lt;span class=\"current\"&gt;{0}&lt;/span&gt;", i); } else { sb.Append(GeneratePageLink(i.ToString(), i)); } } if (end &lt; (pageCount - 3)) { sb.Append("..."); sb.Append(GeneratePageLink((pageCount - 1).ToString(), pageCount - 1)); sb.Append(GeneratePageLink(pageCount.ToString(), pageCount)); } // Next if (this.currentPage &lt; pageCount) { sb.Append(GeneratePageLink("Next", (this.currentPage + 1))); } else { sb.Append("&lt;span class=\"disabled\"&gt;Next&lt;/span&gt;"); } return sb.ToString(); } private string GeneratePageLink(string linkText, int pageNumber) { var pageLinkValueDictionary = new RouteValueDictionary(this.linkWithoutPageValuesDictionary); pageLinkValueDictionary.Add("page", pageNumber); //var virtualPathData = this.viewContext.RouteData.Route.GetVirtualPath(this.viewContext, pageLinkValueDictionary); var virtualPathData = RouteTable.Routes.GetVirtualPath(this.viewContext.RequestContext, pageLinkValueDictionary); if (virtualPathData != null) { string linkFormat = "&lt;a href=\"{0}\"&gt;{1}&lt;/a&gt;"; return String.Format(linkFormat, virtualPathData.VirtualPath, linkText); } else { return null; } } } } </code></pre> <p><strong>PagingExtensions</strong></p> <pre><code>using System; using System.Collections.Generic; using System.Linq; using System.Web.Mvc; using System.Web.Routing; using MvcPaging; namespace MvcPaging { public static class PagingExtensions { public static string Pager(this HtmlHelper htmlHelper, int pageSize, int currentPage, int totalItemCount) { return Pager(htmlHelper, pageSize, currentPage, totalItemCount, null, null); } public static string Pager(this HtmlHelper htmlHelper, int pageSize, int currentPage, int totalItemCount, string actionName) { return Pager(htmlHelper, pageSize, currentPage, totalItemCount, actionName, null); } public static string Pager(this HtmlHelper htmlHelper, int pageSize, int currentPage, int totalItemCount, object values) { return Pager(htmlHelper, pageSize, currentPage, totalItemCount, null, new RouteValueDictionary(values)); } public static string Pager(this HtmlHelper htmlHelper, int pageSize, int currentPage, int totalItemCount, string actionName, object values) { return Pager(htmlHelper, pageSize, currentPage, totalItemCount, actionName, new RouteValueDictionary(values)); } public static string Pager(this HtmlHelper htmlHelper, int pageSize, int currentPage, int totalItemCount, RouteValueDictionary valuesDictionary) { return Pager(htmlHelper, pageSize, currentPage, totalItemCount, null, valuesDictionary); } public static string Pager(this HtmlHelper htmlHelper, int pageSize, int currentPage, int totalItemCount, string actionName, RouteValueDictionary valuesDictionary) { if (valuesDictionary == null) { valuesDictionary = new RouteValueDictionary(); } if (actionName != null) { if (valuesDictionary.ContainsKey("action")) { throw new ArgumentException("The valuesDictionary already contains an action.", "actionName"); } valuesDictionary.Add("action", actionName); } var pager = new Pager(htmlHelper.ViewContext, pageSize, currentPage, totalItemCount, valuesDictionary); return pager.RenderHtml(); } public static IPagedList&lt;T&gt; ToPagedList&lt;T&gt;(this IQueryable&lt;T&gt; source, int pageIndex, int pageSize) { return new PagedList&lt;T&gt;(source, pageIndex, pageSize); } public static IPagedList&lt;T&gt; ToPagedList&lt;T&gt;(this IQueryable&lt;T&gt; source, int pageIndex, int pageSize, int totalCount) { return new PagedList&lt;T&gt;(source, pageIndex, pageSize, totalCount); } public static IPagedList&lt;T&gt; ToPagedList&lt;T&gt;(this IEnumerable&lt;T&gt; source, int pageIndex, int pageSize) { return new PagedList&lt;T&gt;(source, pageIndex, pageSize); } public static IPagedList&lt;T&gt; ToPagedList&lt;T&gt;(this IEnumerable&lt;T&gt; source, int pageIndex, int pageSize, int totalCount) { return new PagedList&lt;T&gt;(source, pageIndex, pageSize, totalCount); } } } </code></pre> <p>Then in my Controller;</p> <pre><code>public class IndexArticlesFormViewModel { public IPagedList&lt;Article&gt; articles {get; set;} public IQueryable&lt;string&gt; userTags { get; set; } public string tag {get; set;} } public ActionResult SearchResults(int? page, string tag) { IndexArticlesFormViewModel fvm = new IndexArticlesFormViewModel(); fvm.articles = ar.Search(tag).ToPagedList(page.HasValue ? page.Value - 1 : 0, 8); fvm.tag = tag; return View(fvm); } [AcceptVerbs(HttpVerbs.Post)] public ActionResult SearchResults(int? page, string tag, FormCollection collection) { if (!string.IsNullOrEmpty(collection["txtSearch"])) return RedirectToAction("SearchResults", new {page = 1, tag = collection["txtSearch"] }); return RedirectToAction("SearchResults", new { page = page, searchTerm = tag }); } </code></pre> <p>And then the View;</p> <pre><code>&lt;div class="pager"&gt; &lt;%= Html.Pager(ViewData.Model.articles.PageSize, ViewData.Model.articles.PageNumber, ViewData.Model.articles.TotalItemCount, new { tag = Model.tag })%&gt; &lt;/div&gt; </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload