Developer

Browse ListView data with .NET's DataPager control

Microsoft .NET 3.5’s DataPager control delivers a paging interface that is tied to the ListView control and communicates with its corresponding ListView control regarding user input. Tony Patton explains how you can use the DataPager control to page through ListView data.

Microsoft .NET 3.5 introduces the DataPager control, which delivers a paging interface that is tied to the ListView control. DataPager also communicates with its corresponding ListView control regarding user input. Here's an explanation of how you can use the DataPager control to page through ListView data.

DataPager's basic properties

You can easily add the DataPager control to a Web Form within Visual Studio. The paging interface appears wherever you place the DataPager control on the page. You may place it before or after the ListView control, as well as within its LayoutTemplate element.

The DataPager control has two basic properties for using it in its default state: PagerControlID and PageSize.

  • PagerControlID is the ID of the ListView control to which it is bound. This is the data that will be paged.
  • PageSize is the number of items and rows to display on each page. The paging interface will appear when/if the PageSize is exceeded.

I'll use the same data source (an XML file) from last week's article about the ListView control to demonstrate its usage:

<?xml version="1.0" encoding="utf-8" ?>

<sites>

<site id="1" url="www.techrepublic.com" title="TechRepublic" />

<site id="2" url="www.cnet.com" title="CNET" />

<site id="1" url="www.google.com" title="Google" />

<site id="2" url="www.gamespot.com" title="GameSpot" />

<site id="1" url="www.builder.com" title="Builder AU" />

<site id="2" url="reviews.cnet.com" title="Reviews" />

<site id="1" url="www.download.com" title="Downloads" />

<site id="2" url="www.cnetnetworks.com/" title="CNET Networks" />

</sites>

The following ASP.NET page contains ListView and DataPager controls to display and page through the data contained in the XML data source. The PageSize property is set to display only two items per page. In this example, the DataPager control displays the individual page links as numbers, along with the first and last buttons to view the first and last data pages.

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebTest._Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >

<head runat="server">

<title>TechRepublic.com - Working with DataPager control</title>
</head>

<body>

<form id="frmDataPager" runat="server">

<asp:DataPager ID="dpExample" runat="server" PagedControlID="lvExample" PageSize="2">

<Fields>

<asp:NextPreviousPagerField ButtonType="Button" ShowFirstPageButton="True"

ShowNextPageButton="False" ShowPreviousPageButton="False" />

<asp:NumericPagerField />

<asp:NextPreviousPagerField ButtonType="Button" ShowLastPageButton="True"

ShowNextPageButton="False" ShowPreviousPageButton="False" />

</Fields>

</asp:DataPager>

<br />

<asp:ListView ID="lvExample" runat="server" DataSourceID="XmlDataSource1">

<AlternatingItemTemplate>

url: <asp:Literal ID="litURL" runat="server" Text='<%# Eval("url") %>' />

<br />

title: <asp:Literal ID="litTitle" runat="server" Text='<%# Eval("title") %>' />

<br />

</li>

</AlternatingItemTemplate>

<LayoutTemplate>

<ul>

<div id="itemPlaceHolder" runat="server" />

</ul>

</LayoutTemplate>

<EmptyDataTemplate>

No data was returned.

</EmptyDataTemplate>

<ItemTemplate>

url: <asp:Literal ID="litURL" runat="server" Text='<%# Eval("url") %>' />

<br />

title: <asp:Literal ID="litTitle" runat="server" Text='<%# Eval("title") %>' />

</li>

</ItemTemplate>

<ItemSeparatorTemplate>

<hr>

</ItemSeparatorTemplate>

</asp:ListView>

<asp:XmlDataSource ID="XmlDataSource1" runat="server" DataFile="~/sites.xml" />

</form></body></html>

Customization

The DataPager control contains a Fields element (which is visible in the previous listing) that allows you to define the appearance of links to pages, previous/next pages, and first/last pages. The links may be buttons, a hyperlink, or an image.

The Fields element may contain one or more of the following elements:

  • NextPreviousPagerField: Provides buttons that enable users to navigate through the pages of data one page at a time or to jump to the first or last page of data. The element contains attributes for hiding, showing, and styling certain buttons.
  • NumericPagerField: Provides a way for users to jump to individual pages according to their page number within the data set. The element contains attributes for showing/hiding links and text, as well as styling what is displayed.
  • TemplatePagerField: Provides the most control, as you can define a custom template for displaying data.
Note: You are not restricted to using one instance of one or more of these elements within the DataPager control; you may choose to use multiple instances of the elements depending on your needs.

The following code snippet includes the source for an instance of the DataPager control that you may use with the previous example. The code uses the three elements within the Fields element of the DataPager control.

The NextPreviousPagerField element is set up to display buttons to access the first and last pages of the data. The NumericPagerField element is set up to display individual links to each page of data, as well as to allow the user to navigate through the data one page at a time via "Prev 2" and "Next 2" links.

The TemplatePagerField element adds a bit of customization to the paging interface. It uses C# to retrieve the total number of rows, the starting row number, and the overall page size to perform calculations. These calculations are used to display "(page x of xx)" text above the pager links and buttons. The TemplatePagerField element lets the user know where they are within the data.

<asp:DataPager ID="dpExample2" runat="server" PagedControlID="ListView1" PageSize="2">

<Fields>

<asp:TemplatePagerField>

<PagerTemplate>

<b>Page

<asp:Label runat="server" ID="CurrentPageLabel"

Text="<%# Container.TotalRowCount>0 ? (Container.StartRowIndex / Container.PageSize) + 1 : 0 %>" />

of

<asp:Label runat="server" ID="TotalPagesLabel"

Text="<%# Math.Ceiling ((double)Container.TotalRowCount / Container.PageSize) %>" />

(<asp:Label runat="server" ID="TotalItemsLabel" Text="<%# Container.TotalRowCount%>" />

records)

<br />

</b>

</PagerTemplate>

</asp:TemplatePagerField>

<asp:NextPreviousPagerField ButtonType="Button" ShowFirstPageButton="true"

ShowNextPageButton="false" ShowPreviousPageButton="false" />

<asp:NumericPagerField PreviousPageText="< Prev 2" NextPageText="Next 2 >"

ButtonCount="10" />

<asp:NextPreviousPagerField ButtonType="Button" ShowLastPageButton="true"

ShowNextPageButton="false" ShowPreviousPageButton="false" />

</Fields>

</asp:DataPager>

These features of the DataPager control, along with the features for displaying data within the ListView control, allow you to build interfaces that meet every need.

Loading data

In response to last week's column, a couple of readers asked how the ListView control loads data. One caveat of the numerous data controls included with .NET is the default approach to loading data from backend data sources. That is, the controls load all data from the data source before displaying a subset on the page.

When paging through data (with or without the DataPager control), a server roundtrip is encountered for each paging request. The result is a performance hit for users; this is especially bothersome when you're dealing with larger data sets. AJAX provides one way to hide the server roundtrip.

The following ASP.NET page shows the ListView and DataPager controls placed within an AJAX-enabled page. It hides the page reloads from the user by requesting data in the background.

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="AJAXTest.aspx.cs" Inherits="WebTest.AJAXTest" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >

<head runat="server">

<title>Ajax Test</title>

</head>

<body>

<form id="frmAjaxTest" runat="server">

<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>

<asp:UpdatePanel ID="UpdatePanel1" runat="server">

<ContentTemplate>

<asp:ListView ID="ListView1" runat="server" DataSourceID="XmlDataSource1">

<AlternatingItemTemplate>

<li style="">

url: <asp:Literal ID="litURL" runat="server" Text='<%# Eval("url") %>' />

<br />

title: <asp:Literal ID="litTitle" runat="server" Text='<%# Eval("title") %>' />

<br />

</li>

</AlternatingItemTemplate>

<LayoutTemplate>

<ul>

<div id="itemPlaceHolder" runat="server" />

</ul>

</LayoutTemplate>

<ItemTemplate>

<li style="">

url: <asp:Literal ID="litURL" runat="server" Text='<%# Eval("url") %>' />

<br />

title: <asp:Literal ID="litTitle" runat="server" Text='<%# Eval("title") %>' />

</li>

</ItemTemplate>

<ItemSeparatorTemplate>

<hr>

</ItemSeparatorTemplate>

</asp:ListView>

<asp:DataPager ID="DataPager1" runat="server" PagedControlID="ListView1" PageSize="2">

<Fields>

<asp:TemplatePagerField>

<PagerTemplate>

<b>Page

<asp:Label runat="server" ID="CurrentPageLabel"
Text="<%# Container.TotalRowCount>0 ? (Container.StartRowIndex / Container.PageSize) + 1 : 0 %>" /> of
<asp:Label runat="server" ID="TotalPagesLabel"
Text="<%# Math.Ceiling ((double)Container.TotalRowCount / Container.PageSize) %>" />

( <asp:Label runat="server" ID="TotalItemsLabel" Text="<%# Container.TotalRowCount%>" /> records)<br /></b>

</PagerTemplate>

</asp:TemplatePagerField>

<asp:NextPreviousPagerField ButtonType="Button" ShowFirstPageButton="true"

ShowNextPageButton="false" ShowPreviousPageButton="false" />

<asp:NumericPagerField PreviousPageText="< Prev 2"NextPageText="Next 2 >"

ButtonCount="2" />

<asp:NextPreviousPagerField ButtonType="Button" ShowLastPageButton="true"

ShowNextPageButton="false" ShowPreviousPageButton="false" />

</Fields>

</asp:DataPager>

<br />

<asp:XmlDataSource ID="XmlDataSource1" runat="server" DataFile="~/sites.xml">

</asp:XmlDataSource>

</ContentTemplate>

</asp:UpdatePanel>

</form></body></html>

While this may seem good for smaller data sets, it does not improve performance with regards to data requests. In my next column, I will examine another way to streamline data access so that only the desired records are loaded.

More options

The introduction of the ListView and DataPager controls with .NET 3.5 shows that Microsoft has listened to developers' complaints concerning display and paging functionality in other controls. The separation of paging functionality into the DataPager control provides more options for developers to build interfaces that allow users to navigate through data.

What features of .NET 3.5 excite you? Do you think the separation of paging into its own control is good? Share your thoughts with the Visual Studio Developer community.

Tony Patton began his professional career as an application developer earning Java, VB, Lotus, and XML certifications to bolster his knowledge.

———————————————————————————————————————————-

Get weekly development tips in your inbox TechRepublic's free Visual Studio Developer newsletter, delivered each Wednesday, contains useful tips and coding examples on topics such as Web services, ASP.NET, ADO.NET, and Visual Studio .NET. Automatically subscribe today!

About

Tony Patton has worn many hats over his 15+ years in the IT industry while witnessing many technologies come and go. He currently focuses on .NET and Web Development while trying to grasp the many facets of supporting such technologies in a productio...

Editor's Picks