Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

C# paging helper class

0.00/5 (No votes)
7 Jan 2012 1  
It's common to extract a single page from a set of records. This utility simplifies the maths involved.

A common way to extract a page from a set of records by checking whether the index of that record is between the index of the first and last items on that page.


While not difficult to do it's easy to accidentally get wrong, if you don't crunch the numbers properly.


This PagingLocation class allows a paging location to be set (like a set of co-ordinates) and then passed to the data access tier to tell it which page to extract.


It includes an IsInPage(int) function which will tell you if the index you provide is within the specified page.


It also has an AbsoluteTotal property which holds the total number of items found in all pages. This is used by the UI to calculate how many pages to let the user choose from.


Here's a crude example of how it's used:


C#
void Page_Load(object sender, EventArgs e)
{
  int pageIndex = 2;
  int pageSize = 10;
  PagingLocation location = new PagingLocation(pageIndex, pageSize);

  ArrayList page = GetPage(location);

  grid.DataSource = page;
  grid.VirtualItemCount = location.AbsoluteTotal;
  grid.DataBind();
}

ArrayList GetPage(PagingLocation location)
{
  ArrayList list = GetAllData();

  location.AbsoluteTotal = list.Count;

  for (int i = 0; i < list.Count; i++)
  {
    if (location.IsInPage(i))
        page.Add(list[i]);
  }
}

Here's a real world example of it being used by a data access component:


C#
protected virtual IEntity[] GetPage(IObjectSet objectSet, PagingLocation location)
{
    int i = 0;
    
    List<IEntity> list = new List<IEntity>();
    
    // Loop through each index in the object set
    for (i = 0; i < objectSet.Count; i++)
    {
        // If it's not in the current page then skip it
        if (location.IsInPage(i))
        {
            // Add the entity to the collection
            list.Add((IEntity)objectSet[i]);
        }
    }
    
    location.AbsoluteTotal = i;
    
    return list.ToArray();
}

http://code.google.com/p/sitestarter/source/browse/trunk/Src/App/SoftwareMonkeys.SiteStarter.Data.Db4o/Db4oDataIndexer.cs#791[^]


Here's the PagingLocation class (with the logging code removed):


C#
using System;
using SoftwareMonkeys.SiteStarter.Diagnostics;

namespace SoftwareMonkeys.SiteStarter.Entities
{
    /// <summary>
    /// Holds the coordinates to a specific page on an index.
    /// </summary>
    public class PagingLocation : IPagingLocation
    {
        private int pageIndex;
        /// <summary>
        /// Gets/sets the current page index.
        /// Note: This is 0 based so PageIndex=(PageNumber-1)
        /// </summary>
        public int PageIndex    
        {
            get { return pageIndex; }
            set { pageIndex = value; }
        }
       
        private int pageSize;
        /// <summary>
        /// Gets/sets the size of each page.
        /// </summary>
        public int PageSize
        {
            get { return pageSize; }
            set { pageSize = value; }
        }
       
        private int absoluteTotal;
        /// <summary>
        /// Gets/sets the absolute total count of all matching items,
        /// including those on ALL pages, not just the specified one.
        /// </summary>
        public int AbsoluteTotal
        {
            get { return absoluteTotal; }
            set { absoluteTotal = value; }
        }
       
        /// <summary>
        /// Empty constructor.
        /// </summary>
        public PagingLocation()
        {
        }
               
        /// <summary>
        /// Sets the page index and page size of the current location.
        /// </summary>
        /// <param name="pageIndex">The index of the current page.</param>
        /// <param name="pageSize">The size of each page.</param>
        public PagingLocation(int pageIndex, int pageSize)
        {
                PageIndex = pageIndex;
                PageSize = pageSize;
        }
       
       
        /// <summary>
        /// Checks whether the specified position is within the specified page.
        /// </summary>
        /// <param name="i">The 0 based index of item to check.</param>
        /// <returns>A bool value indicating whether the specified
        ///   index position is within the specified page.</returns>
        public bool IsInPage(int i)
        {
                // Create the return flag
                bool isInPage = false;
                   
                // Calculate the position of the first item on the page
                int first = (pageIndex * pageSize); // 0 based
               
                // Calculate the position of the last item on the page
                int last = ((pageIndex * pageSize) + pageSize) -1;
                // -1 to make it the last of the page, instead of first item on next page
               
               
                // The position is in the current page if it is between or equal
                // to the first and last items on the page
                isInPage = i >= first
                        && i <= last;
     
                return isInPage;
        }
    }
}

http://code.google.com/p/sitestarter/source/browse/trunk/Src/App/SoftwareMonkeys.SiteStarter.Entities/PagingLocation.cs[^]


To ensure it works properly here are a bunch of unit tests: http://code.google.com/p/sitestarter/source/browse/trunk/Src/App/SoftwareMonkeys.SiteStarter.Entities.Tests/PagingLocationTests.cs[^]

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here