Data Navigation with the ListView, DataPager and SliderExtender Controls
As I mentioned in a previous post, I am currently researching what advantages ASP.NET 3.5's new ListView control would have over the GridView. To continue down this path, I thought it would be a good idea to look into how paging work with the ListView. To direct my research, I created a sample data table that supports paging via the standard paging buttons as well as with a slider bar. Below is a screenshot of the table. As usual you can follow the links below to view the live demo as well as download the code.
If you are interested in the implementation details, they are outlined below.
Overview of the DataPager Control
Before today, I had not yet worked with the DataPager. So to start off, I went out to MSDN's documentation and read through it. To summarize MSDN, the DataPager can be used to display paging navigation controls for other data-bound controls that implement the IPageableItemContainer interface (like the ListView). Additionally,
- The DataPager is associated with its data-bound control by using the PagedControlID, or if you are using a ListView, you just have to place the DataPager inside the ListView's LayoutTemplate (this is the approach I have taken)
- The DataPager contains a Fields collection, that can contain one of 3 different types of DataPagerFields: NextPreviousPagerField, NumericPagerField, and TemplatePagerField. Here is the rundown on these different field types (for this example, I used the TemplatePagerField).
- The DataPager also contains a few properties that can be used in databinding expressions when used in conjunction with the TemplatePagerField. For this sample, I used these properties to bind to the Slider controls value, tooltip as well as to generate the Paging status message (i.e. Page X of Y (Z items)).
One thing that bothers me about my previous paging implementations is how unless the last page of data is exactly the same as the page size, the data table will only be partially filled. The customers dataset taken from the Northwind database is a good example for this. There are 91 rows in the customers table. If you set your pagesize to 10 and navigate to the 9th row, you will only see 1 record (records 91 through 91). I would rather display 10 records (records 82-91).
The DataPager provides a nice way to implement custom paging routines like the one described above. The TemplatePagerField defines a PagerCommand event that occurs when ever a button that is contained with the TemplatePagerField is clicked. So for this sample, I defined First, Previous, Next and Last buttons within the TemplatePagerField and assigned a CommandName to each of them. I then wired the PagerCommand event so that when my buttons are clicked I can calculate the parameters that define which rows are to be included in the next page of data. Here is the sample markup and PageCommand handler that I am using for this sample. If you download the code, you will see I have implemented the behavior outlined above in the PageCommand event handler.
Adding the SliderExtender Control
Besides providing paging buttons, I also wanted to give the user a nice slider bar that they can use to navigate through the data. If you haven't used the AjaxControlToolkit's Slider control before, here is a quick explanation of what it is ...
So I added the Slider control within the TemplatePagerField. By default, the slider allows the user to select values in a range from 0 to 100. I want to ensure that the user could only select a page that was in the valid range of available pages. For the scenario of 91 rows of customer data with a page size of 10, I didn't want the user to be able to select page 11. So I used the following markup to configure the control such that it would place the correct upperbound on the range of valid values:
Secondly, when the moves the Slider to change the selected page I want to post the form back to fetch the next page of data. Because the Slider extends a regular asp:TextBox, you can achieve this by setting the TextBox's AutoPostback attribute to True causing the form to submit when the user changes the Slider's value.
Below is the markup for the Textbox the Slider extends. There are a few important items:
- The Text property uses a databinding expression to determine what the current value should be. This way when the Pager buttons are used for navigation, the Slider's value stays in sync.
- AutoPostBack is set to true do the OnTextChange server event fires when the user changes the selected page
- I added an inline style of "display:none" so the TextBox doesn't flicker when the page is loaded
Well thats the rundown of how I used the ListView, DataPager and Slider controls to build a pretty sweet looking data table. I still have a few items that I would like to add to this example, including:
- Deciding what to do with the pager controls when the number of rows returned is less than the page size
- Add a progress indicator to the pager row that displays during partial postbacks
- Add mouseover images for the pager buttons
Hopefully I can get to these items later.
That's it. Enjoy!