Introduction
To page through data in a control that implements the IPageableItemContainer
interface, DataPager
control can be used. GridView
has its own paging and does not implement IPageableItemContainer
interface. ListView
is the only control that works with DataPager
.
Background
The DataPager
control supports built-in paging user interface (UI). NumericPagerField
object enables users to select a page of data by page number. NextPreviousPagerField
object enables users to move through pages of data one page at a time, or to jump to the first or last page of data. The size of the pages of data is set by using the PageSize
property of the DataPager
control. One or more pager field objects can be used in a single DataPager
control. Custom paging UI can be created by using the TemplatePagerField
object. In the TemplatePagerField
template, the DataPager
control is referenced by using the Container
property which provides access to the properties of the DataPager
control. These properties include the starting row index, the page size, and the total number of rows currently bound to the control.
Using the Code
So let's begin extending the GridView
with the IPageableItemContainer
interface.
Define a new class as below:
public class DataPagerGridView : GridView, IPageableItemContainer
{
public DataPagerGridView() : base()
{
PagerSettings.Visible = false;
}
}
private static readonly object EventTotalRowCountAvailable = new object();
MaximumRows
will be equal to the PageSize
property:
public int MaximumRows
{
get { return this.PageSize; }
}
StartRowIndex
can be calculated from the PageSize
and PageIndex
properties:
public int StartRowIndex
{
get { return this.PageSize * this.PageIndex; }
}
The SetPageProperties
method is called by the DataPager
control every time the control must update the page-related properties. When implemented by a class, the SetPageProperties
method must internally update the MaximumRows
and StartRowIndex
properties by using the values of the maximumRows
and startRowIndex
parameters. So set the Grid with appropriate parameters and bind to right chunk of data.
public void SetPageProperties(int startRowIndex, int maximumRows, bool databind)
{
int newPageIndex = (startRowIndex / maximumRows);
this.PageSize = maximumRows;
if (this.PageIndex != newPageIndex)
{
bool isCanceled = false;
if (databind)
{
GridViewPageEventArgs args = new GridViewPageEventArgs(newPageIndex);
this.OnPageIndexChanging(args);
isCanceled = args.Cancel;
newPageIndex = args.NewPageIndex;
}
if (!isCanceled)
{
this.PageIndex = newPageIndex;
if (databind)
this.OnPageIndexChanged(EventArgs.Empty);
}
if (databind)
this.RequiresDataBinding = true;
}
}
For the DataPager
to render the correct number of page buttons and enable/disable them, it needs to know the total number of rows and the Page Size. But this information is with the GridView
and not known to the DataPager
. As the GridView
control inherits from CompositeDataboundControl
which contains a variant of the CreateChildControls
method, that also takes in a property indicating whether the control is being bound to data or simply re-rendered. The GridView
uses this method to bind to its data source and here we can place a trigger for the TotalRowCountAvailable
event to be raised. Call base control's CreateChildControls
method and determine the number of rows in the source, then fire off the event with the derived data and then we return the original result.
protected override int CreateChildControls(IEnumerable dataSource, bool dataBinding)
{
int rows = base.CreateChildControls(dataSource, dataBinding);
if (this.AllowPaging)
{
int totalRowCount = dataBinding ? rows : ((ICollection)dataSource).Count;
IPageableItemContainer pageableItemContainer = this as IPageableItemContainer;
this.OnTotalRowCountAvailable(new PageEventArgs
(pageableItemContainer.StartRowIndex, pageableItemContainer.MaximumRows, totalRowCount));
if (this.TopPagerRow != null)
this.TopPagerRow.Visible = false;
if (this.BottomPagerRow != null)
this.BottomPagerRow.Visible = false;
}
return rows;
}
public event EventHandler<PageEventArgs> TotalRowCountAvailable
{
add { base.Events.AddHandler(PagingGridView.EventTotalRowCountAvailable, value); }
remove { base.Events.RemoveHandler(PagingGridView.EventTotalRowCountAvailable, value); }
}
protected virtual void OnTotalRowCountAvailable(PageEventArgs e)
{
EventHandler<PageEventArgs> handler =
(EventHandler<PageEventArgs>)base.Events[PagingGridView.EventTotalRowCountAvailable];
if (handler != null)
{
handler(this, e);
}
}
That's all you are done, put the control on aspx page and use DataPager
with GridView
Control.
<cc1:PagingGridView ID="pgvGrid" AllowPaging="True"
OnPageIndexChanging="pgvGrid_PageIndexChanging" runat="server">
</cc1:PagingGridView>
<asp:DataPager ID="pgGrid" runat="server"
PageSize="10" PagedControlID="pgvGrid">
<Fields>
<asp:NextPreviousPagerField ButtonCssClass="command"
FirstPageText="«" PreviousPageText="‹"
RenderDisabledButtonsAsLabels="true"
ShowFirstPageButton="true" ShowPreviousPageButton="true"
ShowLastPageButton="false" ShowNextPageButton="false" />
<asp:NumericPagerField ButtonCount="7"
NumericButtonCssClass="command" CurrentPageLabelCssClass="current"
NextPreviousButtonCssClass="command" />
<asp:NextPreviousPagerField ButtonCssClass="command"
LastPageText="»" NextPageText="›"
RenderDisabledButtonsAsLabels="true"
ShowFirstPageButton="false" ShowPreviousPageButton="false"
ShowLastPageButton="true" ShowNextPageButton="true" />
</Fields>
</asp:DataPager>
protected void pgvGrid_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
pgvGrid.PageIndex = e.NewPageIndex;
LoadGrid();
}
<input type="submit" name="Button1"
value="Generate" id="Button1" />
Column1
| Column2
| Column3
| Column4
| Column5
| Column6
| Column7
| Column8
| Column9
| Column10
| Column11
| Column12
|
R1C1 | R1C2 | R1C3 | R1C4 | R1C5 | R1C6 | R1C7 | R1C8 | R1C9 | R1C10 | R1C11 | R1C12
|
R2C1 | R2C2 | R2C3 | R2C4 | R2C5 | R2C6 | R2C7 | R2C8 | R2C9 | R2C10 | R2C11 | R2C12
|
R3C1 | R3C2 | R3C3 | R3C4 | R3C5 | R3C6 | R3C7 | R3C8 | R3C9 | R3C10 | R3C11 | R3C12
|
R4C1 | R4C2 | R4C3 | R4C4 | R4C5 | R4C6 | R4C7 | R4C8 | R4C9 | R4C10 | R4C11 | R4C12
|
R5C1 | R5C2 | R5C3 | R5C4 | R5C5 | R5C6 | R5C7 | R5C8 | R5C9 | R5C10 | R5C11 | R5C12
|
R6C1 | R6C2 | R6C3 | R6C4 | R6C5 | R6C6 | R6C7 | R6C8 | R6C9 | R6C10 | R6C11 | R6C12
|
R7C1 | R7C2 | R7C3 | R7C4 | R7C5 | R7C6 | R7C7 | R7C8 | R7C9 | R7C10 | R7C11 | R7C12
|
R8C1 | R8C2 | R8C3 | R8C4 | R8C5 | R8C6 | R8C7 | R8C8 | R8C9 | R8C10 | R8C11 | R8C12
|
R9C1 | R9C2 | R9C3 | R9C4 | R9C5 | R9C6 | R9C7 | R9C8 | R9C9 | R9C10 | R9C11 | R9C12
|
R10C1 | R10C2 | R10C3 | R10C4 | R10C5 | R10C6 | R10C7 | R10C8 | R10C9 | R10C10 | R10C11 | R10C12 |
« ‹ 1 2 3 4 5 6 7 ... › »
<input type="submit" name="Button2" value="Save" id="Button2" />