A C# class used to page through an array or list of items in ASP.NET applications.
using System;
using System.Collections.Generic;
using System.Linq;
namespace MyNamespace
{
/// <summary>
/// Pure Pagination Logic in C# / ASP.NET.
/// Article: https://jasonwatmore.com/post/2018/10/17/c-pure-pagination-logic-in-c-aspnet
/// Source: https://github.com/cornflourblue/JW.Pager/blob/master/Pager.cs
/// </summary>
public class Pager
{
/// <summary>
/// Pager class constructor.
/// </summary>
/// <param name="totalItems">The total number of items to be paged</param>
/// <param name="currentPage">The current active page, defaults to the first page.</param>
/// <param name="pageSize">The number of items per page, defaults to 10.</param>
/// <param name="maxPages">The maximum number of page navigation links to display, defaults to 10.</param>
public Pager(
int totalItems,
int currentPage = 1,
int pageSize = 10,
int maxPages = 10
)
{
// calculate total pages
var totalPages = (int) Math.Ceiling((decimal) totalItems / (decimal) pageSize);
// ensure current page isn't out of range
if (currentPage < 1)
{
currentPage = 1;
}
else if (currentPage > totalPages)
{
currentPage = totalPages;
}
int startPage, endPage;
if (totalPages <= maxPages)
{
// total pages less than max so show all pages
startPage = 1;
endPage = totalPages;
}
else
{
// total pages more than max so calculate start and end pages
var maxPagesBeforeCurrentPage = (int) Math.Floor((decimal) maxPages / (decimal) 2);
var maxPagesAfterCurrentPage = (int) Math.Ceiling((decimal) maxPages / (decimal) 2) - 1;
if (currentPage <= maxPagesBeforeCurrentPage)
{
// current page near the start
startPage = 1;
endPage = maxPages;
}
else if (currentPage + maxPagesAfterCurrentPage >= totalPages)
{
// current page near the end
startPage = totalPages - maxPages + 1;
endPage = totalPages;
}
else
{
// current page somewhere in the middle
startPage = currentPage - maxPagesBeforeCurrentPage;
endPage = currentPage + maxPagesAfterCurrentPage;
}
}
// calculate start and end item indexes
var startIndex = (currentPage - 1) * pageSize;
var endIndex = Math.Min(startIndex + pageSize - 1, totalItems - 1);
// create an array of pages that can be looped over
var pages = Enumerable.Range(startPage, (endPage + 1) - startPage);
// update object instance with all pager properties required by the view
TotalItems = totalItems;
CurrentPage = currentPage;
PageSize = pageSize;
TotalPages = totalPages;
StartPage = startPage;
EndPage = endPage;
StartIndex = startIndex;
EndIndex = endIndex;
Pages = pages;
}
/// <summary>
/// The total number of items to be paged.
/// </summary>
public int TotalItems { get; private set; }
/// <summary>
/// The current active page, defaults to the first page.
/// </summary>
public int CurrentPage { get; private set; }
/// <summary>
/// The number of items per page, defaults to 10.
/// </summary>
public int PageSize { get; private set; }
/// <summary>
/// The total amount of pages in the set.
/// </summary>
public int TotalPages { get; private set; }
/// <summary>
/// The starting page number of the set.
/// </summary>
public int StartPage { get; private set; }
/// <summary>
/// The last page in the set of items that can be paged.
/// </summary>
public int EndPage { get; private set; }
/// <summary>
/// The start item index.
/// </summary>
public int StartIndex { get; private set; }
/// <summary>
/// The end item index.
/// </summary>
public int EndIndex { get; private set; }
/// <summary>
/// The enumerable of pages.
/// </summary>
public IEnumerable<int> Pages { get; private set; }
}
}