Using ASP.NET 3.5's ListView and DataPager Controls: Paging Through Data with the ListView and DataPager Controls
By Scott Mitchell
A Multipart Series on ASP.NET's ListView and DataPager Controls |
---|
This article is one in a series of articles on ASP.NET's ListView and DataPager controls, which were introduced with ASP.NET version 3.5.
|
Introduction
The GridView, DetailsView, and FormView controls all support out of the box paging support that can be enabled at the tick of a checkbox. When configured to enable paging, these controls automatically render a paging interface comprised of LinkButtons, Buttons, or ImageButtons. The particular paging interface configuration - whether Next/Previous links are used, whether numeric paging options are used, the text displayed in the various buttons, and so on - are customizable through the data Web controls' properties. While these configuration options are nice, they only allow for a small amount of customization. For instance, the configuration options let you specify if you want the paging interface to appear at the top or bottom of the control (or in both locations). But if you want the paging interface to appear elsewhere on the page, separate from the paging interface, you're out of luck.
The ASP.NET team remedied this problem with the ListView control by decoupling paging support from the ListView control and moving it to a separate, stand-along control, the DataPager. The DataPager control's sole purpose is to render a paging interface and communicate to its corresponding ListView control once the user interacts with the interface (such as choosing to move to the last page of data). This explicit separation between the ListView and DataPager allow for a much greater degree of paging interface customization and positioning, as we will se in this article.
Read on to learn more!
Paging Basics
The DataPager control implements paging through three bits of information:
PagedControlID
- theID
of the ListView control that the DataPager is generating the paging interface for.StartRowIndex
- the index of the first record to display in the current pageMaximumRows
- the maximum number of rows to display per page
StartRowIndex
and MaximumRows
values would be 0 and 10, respectively. To show the second page of data, the values would be 10 and 10. To show the third, they'd be 20 and 10.
There's also the read-only TotalRowCount
property,
which returns the total number of records being paged through.
The DataPager control renders a set of DataPagerFields, with each DataPagerField displaying a paging interface. There .NET Framework version 3.5
includes three pre-built DataPagerFields:
NextPreviousPagerField
,
NumericPagerField
, and
TemplatePagerField
.
The NextPreviousPagerField
displays First/Previous/Next/Last buttons; NumericPagerField
displays a series of page numbers;
TemplatePagerField
creates the paging interface via a template, that we must create.
When a user interacts with the paging interface - by clicking the Next button, perhaps - a
postback occurs and the DataPagerField recognizes that the event was caused by one of its paging user interface elements. The DataPagerField then
determins the new StartRowIndex
and MaximumRows
values and passes them to the DataPager class's
SetPageProperties
method.
The DataPager then calls its associated ListView control's SetPageProperties
method, which causes the ListView to rebind to its data source
and display just the appropriate subset of records.
Default Paging vs. Custom Paging |
---|
The ListView and DataPager controls offer two paging models: default paging and custom paging. The two models provide a tradeoff between performance
and ease of setting up/configuring/using. The SqlDataSource control uses default paging; the ObjectDataSource uses default paging by default, but has
an easy mechanism to indicate that it should use custom paging. Keep in mind that the ListView merely displays data; it's the data source control that
is actually retrieving data from the database.
With default paging, each time a new page of data in displayed, all of the data is requeried from data source control. Once all of the data has been
returned, the ListView selectively displays part of the entire set of data, based on the With custom paging, you, the developer, have to do a bit more work. Rather than just being able to blindly bind the ListView to a data source control and add a DataPager control, you have to configure the data source control to selectively retrieve only those records that should be shown for the particular page. For more information on default and custom paging, and performance and implementation tradeoffs, see Custom Paging in ASP.NET with SQL Server 2005. |
Creating the DataPager and Defining its DataPagerFields
Implementing paging with the ListView and DataPager controls isn't as easy as checking a checkbox, but it's not much more difficult. The download at the end of this article includes two DataPager tutorials, which we will discuss in the remainder of this article. These demos build upon the
SimpleListView.aspx
demo discussed
in Displaying Data with the ListView.
To start, add and configure the ListView control so that it displays data in the format you want. Then, to add paging, add one or more DataPager controls to the page, placing them wherever you want the paging interface to appear. The DataPager may appear within the ListView's LayoutTemplate or elsewhere on the page, outside of the control.
After adding the DataPager, it will appear in the Visual Studio Design view as a gray box, as we have yet to indicate
what DataPagerField(s) to use. To customize the DataPagerFields,
click the Edit Pager Fields link from the DataPager's smar tag. This brings up the Fields dialog box (shown below).
From here you can specify what DataPagerFields to add and their assorted properties. In the Fields dialog box
below, I have added a NextPreviousPagerField
and set the ButtonType
property to Button
(so that it displays the paging interface as Button controls, rather than using the default LinkButtons), and
the ShowFirstPageButton
and ShowLastPageButton
properties to True so that they will be
included along with the Next and Previous buttons.

After clicking OK to close the Fields dialog box, the DataPager's declarative markup updates to include the DataPagerField information; furthermore, the Designer shows the paging interface as First/Previous/Next/Last buttons.
There are two more DataPager properties to set before we're ready to test this page. We need to specify what
ListView the DataPager operates on. To accomplish this, set the DataPager's PagedControlID
property
to the ID
of the ListView on the page. Next, set the DataPager's PageSize
property to indicate how
many records the ListView should show per page (the default value is 10). After making these changes, your DataPager's
declarative markup should look similar to the following:
<asp:DataPager ID="ProductListPagerSimple" runat="server"
|
With this paging interface in place, visit the page through a browser. As the following screen shot shows,
the ListView only displays 5 records per page (because the DataPager's PageSize
property is set to 5).
Moreover, the First and Previous buttons are disabled because we are viewing the first page of data.

The paging interface in the screen shot above is displayed right above the ListView data. But keep in mind that
a single ListView can include multiple DataPager controls. We could augment the paging interface to also
appear at the bottom of the ListView by simply adding an additional DataPager control beneath the ListView and
setting its PagedControlID
and PageSize
properties to the same values as the
other DataPager control.
Specifying Multiple DataPagerFields in the DataPager
The previous example shows using a single DataPagerField in a DataPager (namely, a
NextPreviousPagerField
).
The DataPager is flexible enough to allow for multiple DataPagerFields. This flexibility allows us to create hybrid
paging interfaces, such as a paging interface with numeric pages and First and Last buttons.
To create such an interface, add a DataPager to the page and set its PagedControlID
and PageSize
properties. Then bring up the Fields dialog box and add three DataPagerFields: a NextPreviousPagerField
followed by a NumericPagerField
followed by a NextPreviousPagerField
. Configure the first
NextPreviousPagerField
's properties so that only the First button is shown; likewise, configure
the last NextPreviousPagerField
's properties so that only the Last button is shown. Feel free to
also configure the text displayed in the First and Last buttons - I used <<
for the First button and >>
for Last.
<asp:DataPager ID="ProductListPagerCombo" runat="server"
|
The net result is a hybrid paging interface, as illustrated in the screen shot below. Note that this page has two DataPagers. The one at the top is the First/Previous/Next/Last added from the previous example. The one at the bottom is the hybrid one.

Creating a Custom Paging Interface with the TemplatedPagerField
If neither the
NumericPagerField
nor NextPreviousPagerField
meet your paging interface
requirements, you can create a custom paging interface using the TemplatedPagerField
. With this field,
you, the page developer, are on the hook for creating the paging interface, detecting when the user interacts with
the paging interface, and updating the DataPager and ListView in response.
Let's create a paging interface that enumerates the available pages as ListItems in a DropDownList control, allowing
the user to jump to a particular page by selecting the page number from the list. To achieve this, add a DataPager
control to the page and configure its DataPagerFields, adding a TemplatedPagerField
. The content
for the template can be defined directly in the markup or through the Edit Templates option in the DataPager's smart
tag. In either case, add a DropDownList control to the template. Set its ID
to PageJump
and set its AutoPostBack
property to True.
Our next task is to populate the DropDownList with the various pages. Because this needs to happen each time the
ListView is bound to its data source, create an event handler for the ListView control's DataBound
event
and add the following code:
Protected Sub ProductList_DataBound(ByVal sender As Object, ByVal e As System.EventArgs) Handles ProductList.DataBound
|
The code starts by computing the current page being viewed as well as how many total pages. This information is
gleamed from the DataPager's
Next, the
A loop enumerates the page numbers (from 1 to
If you visit the page at this time you'll see that the DataPager interface includes a DropDownList with a ListItem
for each page. Moreover, selecting a different item from the list causes a postback, but the data displayed isn't changed.
This is because we've yet to handle the DropDownList's
Creating an event handler for a control within a template requires adding the
The above code starts by programmatically referencing the
The net result is a DropDownList that lists each page number. Changing the selection causes a postback and
displays the selected page of data.
Happy Programming!
Further Readings:
StartRowIndex
, TotalRowCount
properties.
PageJump
DropDownList is programmatically referenced. Note that in order to reference
the controls within the TemplatePagerField
we need to use the rather esoteric code:
DataPagerID.Controls(0).FindControl("controlID")
. For some reason, there's no property
for the DataPager control or its TemplatePagerField
that allows access to the template's rendered
contents. Therefore we have to hack it by working directly through the Controls
collection. Ick.
totalPages
) and adds a ListItem for each page.
Finally, the current page's corresponding DropDownList item is selected.
SelectedIndexChanged
event - it's here where we
need to call the DataPager's SetPageProperties
method, passing it the new StartRowIndex
and MaximumRows
values, so that it will update its ListView control's display.
OnEventName=EventHandler
syntax to the control's declarative markup. This can be entered by hand or, alternatively, can be auto-created by
going to the Edit Templates view and double-clicking the DropDownList. In either case, once the event handler is
created add the following code:
Protected Sub PageJump_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs)
Dim PageJumpDDL As DropDownList = CType(sender, DropDownList)
Dim pageNo As Integer = Convert.ToInt32(PageJumpDDL.SelectedValue)
Dim startRowIndex As Integer = (pageNo - 1) * ProductListPager.PageSize
DataPagerID.SetPageProperties(startRowIndex, DataPagerID.PageSize, True)
End Sub
PageJump
DropDownList control in order
to ascertain its SelectedValue
. This requested page number is used to calculate the StartRowIndex
,
and this information (and the DataPager's PageSize
) are passed into the DataPager's
SetPageProperties
method.
Conclusion
Unlike its predecessors, the ListView does not intuitively support paging. Instead, the paging interface has been
moved to a separate Web control, the DataPager. The DataPager's interface is rendered by its DataPagerFields.
The .NET Framework ships with three built-in DataPagerFields: NextPreviousPagerField
, NumericPagerField
,
and TemplatePagerField
. In this article we looked at using all three fields.
Attachments