Skip navigation.
Home

Paging in Datalists and other controls

Anyone who's had to display data in multiple pages in ASP know how much trouble
it can be. Although not very hard, it's tedious at best. This tutorial looks at using the PagedDataSource
class to accomplish the task, and easily. When Microsoft created
ASP.NET, they decided that they'd save developers a lot of time and add support
for this. The most notable control is the DataGrid, which can handle all the
paging details for you as long as you set AllowPaging=true. But some controls
don't have paging support, so what happens if you want to do paging with the
DataList control or the Repeater Control? This is where the PagedDataSource
class comes in.

In this tutorial, we will be looking at the PagedDataSource
class
and we'll see how the it can help us do paging for a DataList control.
This tutorial has simplified much of the code for the sake of readability. It's
aimed for people who have at least a basic understanding of ASP.NET and know how
to do basic databinding already.

PagedDataSource Class

The first thing we have to do is create a paged data source to hold our data
which we want to display using the PagedDataSource
class
. After this is completed, we have to populate our PagedDataSource
object. The PagedDataSource behaves similar to the data properties
associated with the DataGrid, so if you're familiar with the DataGrid, you'll
feel right at home. After your PagedDataSource is populated and you have finished setting all the
properties, the PagedDataSource object can be bounded to a server
control just like you would bind a SqlDataReader to a server control.

Here is some typical code you would write for your paged
data source.

PagedDataSource pg = new PagedDataSource();
pg.DataSource = myHashTable;
pg.AllowPaging = true;
pg.PageSize = 5;

DataSource Property

The DataSource property is used to specify what data will be displayed when the
ASP.NET page is rendered. In this tutorial, the DataSource is being assigned myHashTable.
We always assign the DataSource property with any object (that implements
IEnumerable
) that contains our orignal, un-paged data. Examples of
IEnumerable classes would be hash tables, array lists, arrays, collections,
queues, stacks, etc...

We'll create some dummy data here so that this tutorial will work. This can
be accomplished like this:

Hashtable myHashTable = new Hashtable();
for (int i = 5; i < 505; i++)
   myHashTable.Add(i.ToString(), (i*100).ToString());

We end up with a hash table that has the values of each entry being equal to 100
times the key. There will be 500 records which is sufficient to demonstrate
paging. Again, the DataSource Property is assigned like so:

pg.DataSource = myHashTable;

AllowPaging Propery

This property is pretty self explanatory. We need to assign it a boolean value.
Setting this property to true will allow the object to do paging.

PageSize Property

The PageSize property specifies how many
items will be displayed per page. In our example above, there will be five(5)
items per page.

Next / Prev buttons

Since the PagedDataSource class is not a server control, it won't render
anything on the HTML page so we have to manually deal with the next and previous
buttons for navigation between pages. This can be achived fairly simply by the
use of the ASP.NET button control. Just place two (one for next, one for
previous) buttons on your page and assign the OnClick event to increment or
decrement the page.

Here are examples of the two methods you could use:

public void Prev_Click(Object sender, EventArgs e) {
   Response.Redirect(Request.CurrentExecutionFilePath + "?Page=" + (pg.CurrentPageIndex - 1));
}

// Move to next page
public void Next_Click(Object sender, EventArgs e) {
   Response.Redirect(Request.CurrentExecutionFilePath + "?Page=" + (pg.CurrentPageIndex + 1));
}

The CurrentPageIndex is the property of the PagedDataSource which
gives you
an integer value for its current page. We can either increment or decrement this
and send it in a query string. This tutorial shows how to increment the page by
sending the user to a new URL. I would recommend this be used instead of a
normal postback. This will allow your visitors to bookmark a certain page
instead of bookmarking only the first page.

Another thing we have to watch out for is to disable the previous button when
on the first page and disable the next button when on the last page. This can be
accomplished by using the PagedDataSource's IsFirstPage and IsLastPage property
like so:

// Enable and/or disable the previous and next buttons
btnPrev.Enabled = !pg.IsFirstPage;
btnNext.Enabled = !pg.IsLastPage;

Finally, since we redirect the user to a URL with the page number in the query
string, we have to catch this when the page is being rendered and display the
correct page.

// Move to the appropriate page based on the query string.
try {
   pg.CurrentPageIndex = Int32.Parse(Request["Page"].ToString());
// Go to first page if Page isn't specified or if people tries to mess with the query string
} catch (Exception ex) {

   pg.CurrentPageIndex = 0;
}

Alternatively, the same thing could be accomplished by using ASP.NET Hyperlink
server controls and assigning the proper URL when the page is being rendered.

Displaying page information

Above, we briefly mentioned the CurrentPageIndex property. This property has
both get and set, so it is useful to display this information about the current
page to the user.

Putting it all together

Now that we've finished discussing the individual elements that needs to be
completed, we can put everything together.

Below is a full aspx page with all the code in this tutorial.

<%@ Page Language="C#" Debug="true" %>
<%@ Import Namespace="System.Xml" %>
<html>
<head>
<title>Paged Data Source Example</title>
<script language="C#" runat="server">
PagedDataSource pg;

void Page_Load(object sender, EventArgs e)
{
Hashtable myHashTable = new Hashtable();
for (int i = 5; i < 505; i++)
myHashTable.Add(i.ToString(), (i*100).ToString());

// Create a new PAGED data source and config the settings.
pg = new PagedDataSource();
pg.DataSource = myHashTable;
pg.AllowPaging = true;
pg.PageSize = 5;
// Move to the appropriate page based on the query string.
try {
pg.CurrentPageIndex = Int32.Parse(Request["Page"].ToString());
} catch (Exception ex) {
pg.CurrentPageIndex = 0;
}
// Enable and/or disable the previous and next buttons
btnPrev.Enabled = !pg.IsFirstPage;
btnNext.Enabled = !pg.IsLastPage;
// Display which is the current page being displayed
lblCurrentPage.Text = "Page: " + (pg.CurrentPageIndex + 1).ToString();

// Attach data source to the datalist
dlStocks.DataSource = pg;
// Bind data.
dlStocks.DataBind();
}

// Return to previous page
public void Prev_Click(Object sender, EventArgs e)
{
Response.Redirect(Request.CurrentExecutionFilePath + "?Page=" + (pg.CurrentPageIndex - 1));
}

// Move to next page
public void Next_Click(Object sender, EventArgs e)
{
Response.Redirect(Request.CurrentExecutionFilePath + "?Page=" + (pg.CurrentPageIndex + 1));
}
</script>
</head>
<body>
<form runat="server">
<asp:DataList id="dlStocks" runat="server">
<ItemTemplate>
<hr size="0">
Name: <%# DataBinder.Eval(Container.DataItem, "Key") %><br />
Price: <%# DataBinder.Eval(Container.DataItem, "Value") %></a><br />
</ItemTemplate>
</asp:DataList>
<hr size="0">
<asp:LinkButton id="btnPrev" Text="&lt;&lt; Prev" OnClick="Prev_Click" runat="server"/>
<asp:Label id="lblCurrentPage" runat="server"/>
<asp:LinkButton id="btnNext" Text="Next &gt;&gt;" OnClick="Next_Click" runat="server"/>
</form>
</body>
</html>

Closing

The PagedDataSource class gives developers the flexibility to add paging to all
server controls (which display data). Using the PagedDataSource class also
allows developers the flexibility of creating their own navigation. Something we
haven't discussed is that the data source in this tutorial has 500 records.
Going to page 62 may be tiresome because it would require 61 clicks. We could
have simply added buttons, in addition to the next/prev buttons, to move 10
pages ahead or 10 pages behind.

Be sure to check out MSDN PagedDataSource Class Documentation.