When you think ASP, think...
Recent Articles
All Articles
ASP.NET Articles
ASPFAQs.com
Message Board
Related Web Technologies
User Tips!
Coding Tips
Search

Sections:
Book Reviews
Sample Chapters
Commonly Asked Message Board Questions
JavaScript Tutorials
MSDN Communities Hub
Official Docs
Security
Stump the SQL Guru!
Web Hosts
XML
Information:
Advertise
Feedback
Author an Article

ASP ASP.NET ASP FAQs Message Board Feedback
 
Print this Page!
Published: Wednesday, August 18, 2004

Adding Paging Support to the Repeater or DataList with the PagedDataSource Class

By Harrison Enholm


Introduction


When building ASP.NET Web applications, one of the most common tasks is displaying data. ASP.NET offers a bounty of data Web controls that make displaying data a breeze, but the most powerful data Web control - the DataGrid - imposes some limitations on the flexibility of laying out the data on the Web page. Recently I found myself needing a more flexible layout than the DataGrid's rigid column/row orientation, so I decided to go with the Repeater control so I could easily customize the HTML markup emitted.

The Repeater control is great for situations like this, where you need a finer degree of control over the emitted HTML in order to layout the content in a unique or precise manner. One drawback to the Repeater is that it does not have built-in paging capability, a feature the DataGrid offers. Since I would need to display potentially hundreds of records in the catalog, it was essential that I provided paging support for the Repeater.

Fortunately there is a class in the .NET Framework that was designed to provide paged access to a data source. This class, the PagedDataSource class, can be used by either the Repeater or DataGrid to mimic the paging capabilities of the DataGrid. Using the PagedDataSource class you'll have to write a bit more code than you would when using the DataGrid, but the amount and complexity of the code you do have to write is fairly low. In this article we'll examine this class, and see a specific example of how to implement paging with a Repeater control.

- continued -

Paging with the PagedDataSource Class


The PagedDataSource class, found in the System.Web.UI.WebControls namespace, encapsulates the properties needed to enable paging for a control. To implement paging in a control with the PagedDataSource class, you'll need to perform the following steps:
  1. Get the data that you want to page through. This can be an array, a DataSet, a DataReader, or any other object that can be assigned to a data Web control's DataSource property.
  2. Create the PagedDataSource instance, and assign the data to page through to the PagedDataSource's DataSource property.
  3. Set the PagedDataSource class's paging properties, such as setting AllowPaging to True, and setting PageSize (to indicate how many records per page to show).
  4. Assign the PagedDataSource instance to the data Web control's DataSource property and call the data Web control's DataBind() method.

Example: Creating a Pageable Repeater


To examine how to use the PagedDataSource class to provide pagination support in a Repeater, let's create a pageable Repeater. First we need to build the HTML content that includes the Repeater control; note that the HTML contains not only a Repeater, but also the paging navigation buttons and a Label indicating the page number. (Notice that the Repeater's ItemTemplate is very simple in this example, and the same output could be possible with a DataGrid; but the concept holds - you could alter the Repeater's markup to allow for a much richer output that would not be possible with the DataGrid.)

<table width="100%" border="0">
   <tr>
      <td>  Repeater control with Paging functionality</td>
   </tr>
   <tr>
      <td>  <asp:label id="lblCurrentPage" runat="server"></asp:label></td>
   </tr>
   <tr>
      <td>  <asp:button id="cmdPrev" runat="server" text=" << "></asp:button>
          <asp:button id="cmdNext" runat="server" text=" >> "></asp:button></td>
   </tr>
</table>

<table border="1">
   <asp:repeater id="repeaterItems" runat="server">
      <itemtemplate>
         <tr>
            <td>  <b><%# DataBinder.Eval(Container.DataItem, "ItemName") %></b></td>
            <td>  <b><%# DataBinder.Eval(Container.DataItem, "ItemDescription") %></b></td>
            <td>  <b><%# DataBinder.Eval(Container.DataItem, "ItemPrice") %></b></td>
            <td>  <b><%# DataBinder.Eval(Container.DataItem, "ItemInStock") %></b></td>
         </tr>
      </itemtemplate>
   </asp:repeater>
</table>

The HTML for a pageable Repeater can be as simple or as involved as you want. The code, though, is pretty straightforward. The first step is to write the code that will do all of the work of displaying the correct page of data in the Repeater. This is accomplished by first reading in the data to be paged through. For this example, I just created an XML file (Items.xml) containing some sample data; this XML file is available in the code download at the end of this article.

// Read sample item info from XML document into a DataSet
DataSet Items = new DataSet();
Items.ReadXml(MapPath("Items.xml"));

Now that we have the data to page through, we need to create a PagedDataSource instance and specify its DataSource property and other germane properties.

// Populate the repeater control with the Items DataSet
PagedDataSource objPds = new PagedDataSource();
objPds.DataSource = Items.Tables[0].DefaultView;

// Indicate that the data should be paged
objPds.AllowPaging = true;

// Set the number of items you wish to display per page
objPds.PageSize = 3;

The PagedDataSource also has a CurrentPageIndex, which indicates what page of data to display. The following code shows assigning this property. Note that CurrentPageIndex is assigned the value of a page-level property called CurrentPage. We'll discuss this page-level property shortly.

// Set the PagedDataSource's current page
objPds.CurrentPageIndex = CurrentPage - 1;

Finally, we need to enable/disable the navigation buttons depending if we're on the first/last page, as well as update the Label Web control to indicate what page is currently being viewed. We can easily determine if we're on the first/last page using the PagedDataSource's IsFirstPage and IsLastPage properties.

lblCurrentPage.Text = "Page: " + (CurrentPage + 1).ToString() + " of "
    + objPds.PageCount.ToString();

// Disable Prev or Next buttons if necessary
cmdPrev.Enabled = !objPds.IsFirstPage;
cmdNext.Enabled = !objPds.IsLastPage;

Finally, we display the correct page of data by binding the PagedDataSource object to the Repeater.

repeaterItems.DataSource = objPds;
repeaterItems.DataBind();

Examining the CurrentPage Page-Level Property


Back in our earlier code example, we assigned the PagedDataSource object's CurrentPageIndex property to a page-level property called CurrentPage. In order to remember the page of data to display across postbacks, it is important that the page index be maintained in the view state. This page-level property essentially wraps the complexity of reading from / writing to the view state, providing a convenient way to get and set the current page index. Here is the CurrentPage property:

public int CurrentPage
{
   get
   {
      // look for current page in ViewState
      object o = this.ViewState["_CurrentPage"];
      if (o == null)
         return 0; // default page index of 0
      else
         return (int) o;
   }

   set
   {
      this.ViewState["_CurrentPage"] = value;
   }
}

Moving Between Pages of Data


To move from one page of data to another, the user visiting the Web page can click the next or previous buttons. These buttons, when clicked, cause a postback, and run server-side code that updates the CurrentPage property and rebinds the data to the Repeater.

private void cmdPrev_Click(object sender, System.EventArgs e)
{
   // Set viewstate variable to the previous page
   CurrentPage -= 1;

   // Reload control
   ItemsGet();
}

private void cmdNext_Click(object sender, System.EventArgs e)
{
   // Set viewstate variable to the next page
   CurrentPage += 1;

   // Reload control
   ItemsGet();
}

ItemsGet() is a page-level method (whose code we examined earlier) that contains the code to create the PagedDataSource object and bind it to the Repeater.

Conclusion


As you can see, adding the paging functionality to the Repeater control is fairly simple thanks to the PagedDataSource. You should now be able to create a paging Repeater control that will fit your needs; the lessons learned here can also be applied to adding pagination support to a DataList. Having the ability to page with a Repeater or DataList control will greatly enhance the usefulness of these data Web controls and, hopefully, you will find yourself using these versatile controls more often.

Happy Programming!

  • By Harrison Enholm


  • Download the complete source code (in a ZIP file)
  • View a live demo!


  • ASP.NET [1.x] [2.0] | ASPMessageboard.com | ASPFAQs.com | Advertise | Feedback | Author an Article