Reinventing the Paged IEnumerable, Weigert Style!
- by adweigert
I am pretty sure someone else has done this, I've seen variations as PagedList<T>, but this is my style of a paged IEnumerable collection. I just store a reference to the collection and generate the paged data when the enumerator is needed, so you could technically add to a list that I'm referencing and the properties and results would be adjusted accordingly.
I don't mind reinventing the wheel when I can add some of my own personal flare ...
// Extension method for easy use
public static PagedEnumerable AsPaged(this IEnumerable collection, int currentPage = 1, int pageSize = 0)
{
Contract.Requires(collection != null);
Contract.Assume(currentPage >= 1);
Contract.Assume(pageSize >= 0);
return new PagedEnumerable(collection, currentPage, pageSize);
}
public class PagedEnumerable : IEnumerable
{
public PagedEnumerable(IEnumerable collection, int currentPage = 1, int pageSize = 0)
{
Contract.Requires(collection != null);
Contract.Assume(currentPage >= 1);
Contract.Assume(pageSize >= 0);
this.collection = collection;
this.PageSize = pageSize;
this.CurrentPage = currentPage;
}
IEnumerable collection;
int currentPage;
public int CurrentPage
{
get
{
if (this.currentPage > this.TotalPages)
{
return this.TotalPages;
}
return this.currentPage;
}
set
{
if (value < 1)
{
this.currentPage = 1;
}
else if (value > this.TotalPages)
{
this.currentPage = this.TotalPages;
}
else
{
this.currentPage = value;
}
}
}
int pageSize;
public int PageSize
{
get
{
if (this.pageSize == 0)
{
return this.collection.Count();
}
return this.pageSize;
}
set
{
this.pageSize = (value < 0) ? 0 : value;
}
}
public int TotalPages
{
get
{
return (int)Math.Ceiling(this.collection.Count() / (double)this.PageSize);
}
}
public IEnumerator GetEnumerator()
{
var pageSize = this.PageSize;
var currentPage = this.CurrentPage;
var startCount = (currentPage - 1) * pageSize;
return this.collection.Skip(startCount).Take(pageSize).GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
}