C# paging helper class





2.00/5 (1 vote)
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:
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:
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):
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[^]