Extending DataPager: Creating a google analytics data pager
Author: Luis Ramirez.
March 25, 2008.
Download GooglePagerField webcontrol
The DataPager is one of the new webcontrols deployed with ASP.NET 3.5. The DataPager webcontrol allows you to add paging support for databound controls that implements
the IPageableItemContainer interface. For example, you can use the DataPager webcontrol to
give paging support to the new ListView webcontrol.
One of the things that seems more interesting about the DataPager webcontrol
is the ability to extend its functionality with a new one that fits your needs best.
Extending the DataPager webcontrol is exactly what we are going to do now. We are
going to create a custom DataPager that gives a similar functionality than the pager found in Google analytics
(see Figure 1).

Figure 1.
Google Analytics ASP.NET Grid Serie
The Google Analytics ASP.NET Grid Serie will show you how to create an ASP.NET Grid that recreates the appearance and behavior of the Grid displayed in the Google Analytics web site.
Understanding the DataPager webcontrol and DataPagerField
When you have a huge amount of data most of the times you don't want to display all the data at once. For performance and usability issues is better to display only a set of records and not all the records at once. The DataPager webcontrol allows you to split your data into pages and every time that a user select a page he will see the set of records corresponding to the selected page. For example, if you have
100 data records you can use the DataPager webcontrol to display only 10 records per page. The first page displays the records 1-10, the second page displays the records 11-20, and so on.
To start using the DataPager webcontrol you only need to drag and drop a DataPager
webcontrol to your webform. The DataPager webcontrol has two paging styles by default:
- Numeric style (NumericPagerField): Allows the user to browse a set of records selecting a page number.

Figure 2.
- Next and previous style (NextPreviousPagerField): Allows the user to browse a set of records selecting the first, previous, next and last page.

Figure 3.
If you want to use the numeric style to page your data you need to add the NumericPagerField to the Fields collection of the DataPager webcontrol.
1
<asp:DataPager ID="DataPager1" runat="server" PagedControlID="ListView1">
2
<Fields>
3
<asp:NumericPagerField />
4
</Fields>
5
</asp:DataPager>
If you want to use the next and previous style to page your data you need to add the NextPreviousPagerField to the Fields collection of the DataPager webcontrol.
1
<asp:DataPager ID="DataPager1" runat="server" PagedControlID="ListView1">
2
<Fields>
3
<asp:NextPreviousPagerField />
4
</Fields>
5
</asp:DataPager>
The DataPager webcontrol actually doesn't render the appearance neither of the numeric style nor of the next and previous style. The NumericPagerField and NextPreviousPagerField classes handle the rendering of the numeric and the next and previous style, respectively.
The NumericPagerField and the NextPreviousPagerField classes are known as navigation
controls, both derive from the . If you want to create a custom appearance and functionality for the DataPager
control then you can use the TemplatePagerField class or you can create a custom
navigation control. For the purpose of this article we will create our own navigation
control for the DataPager webcontrol.
GooglePagerField: Google analytics navigation control
Now we are going to talk about our navigation control, the GooglePagerField. The
GooglePagerField allows you to specify the first record to be displayed, set the
maximum number of records displayed per page and move to the previous and next page.

Figure 4.
Extending DataPagerField
Now is time to create our Google data pager navigation control. We are not going to extend the DataPager class, what we are going to do is to extend the DataPagerField class. The DataPagerField class provides the basic functionality of a navigation control.
I we want to extend the DataPagerField class we need to implement the functionality of the CreateField, CreateDataPagers and HandleEvent methods.
1
public class GooglePagerField : DataPagerField
2
...{
3
protected override DataPagerField CreateField()
4
...{
5
}
6
7
public override void CreateDataPagers(DataPagerFieldItem container, int startRowIndex, int maximumRows,
8
int totalRowCount, int fieldIndex)
9
...{
10
}
11
12
public override void HandleEvent(CommandEventArgs e)
13
...{
14
}
15
}

CreateField method
Returns an instance of the GooglePagerField class.
1
protected override DataPagerField CreateField()
2
...{
3
return new GooglePagerField();
4
}
CreateDataPagers method
Creates the UI for our data pager. The table 1 explains the meaning of the parameters of the CreateDataPagers method.
| container |
An instance that implements the INamingContainer interface. The DataPagerFieldItem instance is used to build a unique identifier for the controls created in the CreateDataPagers method. |
| startRowIndex |
Specify the index of the data row that will be displated at the beginning. |
| maximumRows |
Specify the maximum number of data rows that will be displayed by page. For example, if you have a datasource with 100 records you may specify that 10 records per page will be displayed by maximum. |
| totalRowCount |
Specify the total data rows that your datasource has. For example, 100 records. |
| fieldIndex |
Specify the position of our GooglePagerField within the fields collection of the DataPager webcontrol. |
The CreateDataPagers method creates the UI that will be displayed to the user. The CreateDataPagers method checks whether to render the UI using the values returned by the event raised by a user action or using the values passed in the query string of the ASPX webform.
1
public override void CreateDataPagers(DataPagerFieldItem container, int startRowIndex, int maximumRows,
2
int totalRowCount, int fieldIndex)
3
...{
4
this._startRowIndex = startRowIndex;
5
this._maximumRows = maximumRows;
6
this._totalRowCount = totalRowCount;
7
8
if (string.IsNullOrEmpty(base.DataPager.QueryStringField))
9
...{
10
this.CreateDataPagersForCommand(container, fieldIndex);
11
}
12
else
13
...{
14
this.CreateDataPagersForQueryString(container, fieldIndex);
15
}
16
}
The CreateDataPagersForCommand method creates the controls used to give the functionality to our GooglePagerField.
1
private void CreateDataPagersForCommand(DataPagerFieldItem container, int fieldIndex)
2
...{
3
//Goto item texbox
4
this.CreateGoToTexBox(container);
5
6
//Control used to set the page size.
7
this.CreatePageSizeControl(container);
8
9
//Set of records - total records
10
this.CreateLabelRecordControl(container);
11
12
//Previous button
13
if (this._showPreviousPage)
14
...{
15
container.Controls.Add(this.CreateControl("Prev", this.PreviousPageText, fieldIndex,
16
this.PreviousPageImageUrl, this._showPreviousPage));
17
this.AddNonBreakingSpace(container);
18
}
19
20
//Next button
21
if (this._showNextPage)
22
...{
23
container.Controls.Add(this.CreateControl("Next", this.NextPageText, fieldIndex,
24
this.NextPageImageUrl, this._showNextPage));
25
this.AddNonBreakingSpace(container);
26
}
27
}
HandleEvent method
Handles the events raised by the objects created in the CreateDataPagers method. The table 3 shows you the commands handled by the HandleEvent method.
| UpdatePageSize |
This command occurs when the user select an item in the 'Show rows' dropdown list. |
| GoToItem |
This command occurs when the user specify a value in the 'Go to' textbox and press enter. |
| Prev |
This command occurs when the user select the previous page button. |
| Next |
This command occurs when the user select the next page button. |
1
public override void HandleEvent(CommandEventArgs e)
2
...{
3
if (string.Equals(e.CommandName, "UpdatePageSize"))
4
...{
5
base.DataPager.PageSize = Int32.Parse(e.CommandArgument.ToString());
6
base.DataPager.SetPageProperties(this._startRowIndex, base.DataPager.PageSize, true);
7
return;
8
}
9
10
if (string.Equals(e.CommandName, "GoToItem"))
11
...{
12
int newStartRowIndex = Int32.Parse(e.CommandArgument.ToString());
13
base.DataPager.SetPageProperties(newStartRowIndex, base.DataPager.PageSize, true);
14
return;
15
}
16
17
if (string.IsNullOrEmpty(base.DataPager.QueryStringField))
18
...{
19
if (string.Equals(e.CommandName, "Prev"))
20
...{
21
int startRowIndex = this._startRowIndex - base.DataPager.PageSize;
22
if (startRowIndex < 0)
23
...{
24
startRowIndex = 0;
25
}
26
base.DataPager.SetPageProperties(startRowIndex, base.DataPager.PageSize, true);
27
}
28
else if (string.Equals(e.CommandName, "Next"))
29
...{
30
int nextStartRowIndex = this._startRowIndex + base.DataPager.PageSize;
31
32
if (nextStartRowIndex > this._totalRowCount)
33
nextStartRowIndex = this._totalRowCount - base.DataPager.PageSize;
34
35
if (nextStartRowIndex < 0)
36
nextStartRowIndex = 0;
37
38
base.DataPager.SetPageProperties(nextStartRowIndex, base.DataPager.PageSize, true);
39
}
40
}
41
}
ButtonDropDownList webcontrol
The ButtonDropDownList is a custom dropdownlist webcontrol created to allow the user to select the page size. The ButtonDropDownList webcontrol implements the IPostBackEventHandler. The IPostBackEventHandler allows to the ButtonDropDownList webcontrol to raise a Command event which can be handled by the GooglePagerField class.
1
public class ButtonDropDownList : DropDownList, IPostBackEventHandler
2
...{
3
}
The RaisePostBackEvent method raises the command event which is handled by the HandledEvent method of the GoogleDataPagerField class. The selected page size is passed as the event argument.
1
void IPostBackEventHandler.RaisePostBackEvent(string eventArgument)
2
...{
3
this.CommandArgument = "0";
4
5
if (base.SelectedItem != null)
6
this.CommandArgument = this.SelectedItem.Value;
7
8
this.RaisePostBackEvent(eventArgument);
9
}
10
11
protected virtual void RaisePostBackEvent(string eventArgument)
12
...{
13
if (this.CausesValidation)
14
...{
15
this.Page.Validate(this.ValidationGroup);
16
}
17
this.OnCommand(new CommandEventArgs(this.CommandName, this.CommandArgument));
18
}
19
20
protected virtual void OnCommand(CommandEventArgs e)
21
...{
22
CommandEventHandler handler = (CommandEventHandler)base.Events[EventCommand];
23
if (handler != null)
24
...{
25
handler(this, e);
26
}
27
//It bubbles the event to the HandleEvent method of the GoogleDataPagerField class.
28
base.RaiseBubbleEvent(this, e);
29
}
ButtonTextBox webcontrol
The ButtonTextBox is a custom textbox webcontrol created to allow the user to display the data records beginning at the specified record. The ButtonTextBox webcontrol implements the IPostBackEventHandler. The IPostBackEventHandler allows to the ButtonTextBox webcontrol to raise a Command event which can be handled by the GooglePagerField class.
1
public class ButtonTextBox : TextBox, IPostBackEventHandler
2
...{
3
}
The RaisePostBackEvent method raises the command event which is handled by the HandledEvent method of the GoogleDataPagerField class. The specified record is passed as the event argument.
1
void IPostBackEventHandler.RaisePostBackEvent(string eventArgument)
2
...{
3
this.CommandArgument = base.Text;
4
this.RaisePostBackEvent(eventArgument);
5
}
Using the GoogleDataPagerField
To use the Google data pager in your web applications you only need to add a GoogleDataPagerField to the fields collection of the DataPager class.
1
<asp:ListView ID="ListView1" runat="server" DataSourceID="AccessDataSource1" ItemPlaceholderID="itemPlaceHolder">
2
<LayoutTemplate>
3
<table class="tableInfo">
4
<tr>
5
<th>ID</th>
6
<th>First name</th>
7
<th>Last name</th>
8
</tr>
9
<asp:PlaceHolder runat="server" ID="itemPlaceholder"></asp:PlaceHolder>
10
<tr>
11
<td colspan="3">
12
<asp:DataPager ID="DataPager1" runat="server" PagedControlID="ListView1" PageSize="5" >
13
<Fields>
14
<SqlNetFrameworkWebControls:GooglePagerField
15
NextPageImageUrl="~/Images/button_arrow_right.gif"
16
PreviousPageImageUrl="~/Images/button_arrow_left.gif" />
17
</Fields>
18
</asp:DataPager>
19
</td>
20
</tr>
21
</table>
22
</LayoutTemplate>
23
<ItemTemplate>
24
<tr>
25
<td><%...# Eval("PlayerId") %></td>
26
<td><%...# Eval("FirstName") %></td>
27
<td><%...# Eval("LastName") %></td>
28
</tr>
29
</ItemTemplate>
30
</asp:ListView>
Conclusion
The DataPager webcontrol separates the paging functionality from the databound webcontrol. It allows you to have the freedom to customize the paging appearance and functionality
to your own needs.