TECHNOLOGIES: ASP.NET | ADO.NET | SQL Server
One Page at a Time
Add versatility to your data access with the DataGrid control.
By Wayne S. Freeze
Back in the days of mainframes, you were limited to 25 lines of information to display on a single screen. If you sent more information to a user than what would fit on a single screen, the data would be broken up into small batches known as pages.
When programmers started creating Web-based applications, many took advantage of the fact that they could create Web pages that were as long as necessary. In practice, this proved to be a poor idea. Long Web pages load slowly and information on the page is difficult for users to locate because they had to search through so much information. Hence, most Web programmers have gone back to the concept of pages to display their data.
ASP.NET s DataGrid control allows you to break up your data into a series of individual pages by doing nothing more than setting a few properties when you add the control to your program. Although this feature lets you add paging to your application easily, you can choose only from two methods that a user can use to page through your data.
The first method uses two LinkButtons: Previous and Next. You can change the text, but your users are forced to view your data in sequence; they can t skip over pages. The other method displays a series of page numbers that allow your users to jump randomly through the data in the DataGrid. If the DataGrid has more than 10 pages of data, your user will click on another LinkButton to display the next 10 page numbers.
Although these techniques are useful for many applications, I like to allow a user to jump to the first and last pages of data without necessarily viewing the pages in between. This can be very useful if you allow the user to sort the data in the grid because they might want to start at the end and work their way to the front.
Extend DataGrid Paging
Fortunately, there are several ways to replace default paging controls with your own, and in this article I m going to explore the easiest. In this technique, you hide the default paging controls and replace them with yours. Then you can use the paging properties (PageSize, PageCount, and CurrentPageIndex) to control the paging process.
To enable paging and hide the default paging controls, set
the AllowPaging property to True, then set the PagerStyle s Visible property to
False to prevent the default paging controls from being displayed. You also
could enter this element inside the
Next, you need a series of Web controls that allow the user to display the various pages in the DataGrid. You can choose any controls that will trigger an event when clicked. In this article s example, I use a combination of LinkButtons and Label controls (see Figure 1) to display the first and last row number for that page. Depending on the position in the DataGrid, the Text values for each of these controls might change and, in some cases, the control s Visible property will be set to False.
Figure 1. A combination of LinkButtons and Labels allows your users to see which page they are viewing and control which pages they want to view next.
In the center of this set of controls is a Label control that displays the rows associated with the current page. To the right and left of these controls are several LinkButton controls that move to a new page relative to the current page. At each end of the set of controls is a LinkButton and a Label control that let the user jump to the first or last page in the DataGrid. The associated Label control is displayed only if there is a gap in pages between the relative controls and the first or last controls.
The Click event of each LinkButton calls the UpdatePageLocation subroutine, which displays the specified page and updates all the text information displayed in the LinkButtons and Labels. For example, if you want to display the first page in the DataGrid, you would call the UpdatePageLocation routine with a value of zero:
If you want to move to the next page, you would call UpdatePageLocation:
Switch to a New Page
The UpdatePageLocation subroutine (see Figure 2) takes a single parameter that indicates the location of the new page. The routine begins by verifying that a valid Session object exists containing the DataView of the rows to be displayed in the DataGrid.
Sub UpdatePageLocation(page As Integer)
Dim dv As DataView
dv = Session("Customers")
If dv Is Nothing Then
If page < 0 or page > DataGrid1.PageCount -1 Then
DataGrid1.CurrentPageIndex = page
SetLinkButton(dv, Minus4, DataGrid1.CurrentPageIndex -4)
SetLinkButton(dv, Minus3, DataGrid1.CurrentPageIndex -3)
SetLinkButton(dv, Minus2, DataGrid1.CurrentPageIndex -2)
SetLinkButton(dv, Minus1, DataGrid1.CurrentPageIndex -1)
Current.Text = ComputeRowRange(dv, DataGrid1.CurrentPageIndex)
SetLinkButton(dv, Plus1, DataGrid1.CurrentPageIndex + 1)
SetLinkButton(dv, Plus2, DataGrid1.CurrentPageIndex + 2)
SetLinkButton(dv, Plus3, DataGrid1.CurrentPageIndex + 3)
SetLinkButton(dv, Plus4, DataGrid1.CurrentPageIndex + 4)
DataGrid1.DataSource = dv
Figure 2. The UpdatePageLocation subroutine takes care of all the details for changing the CurrentPageIndex property of the DataGrid to the new location and updating all the information displayed in the LinkButton and Label controls.
UpdatePageLocation continues by verifying that the page parameter contains a valid page number within the DataGrid. If so, the CurrentPageIndex property is changed to reflect the new page. The FixupFirst routine (along with the FixupLast routine) handles the special case of the First and Last LinkButtons, which are displayed only when necessary. The series of calls to SetLinkButton updates the value displayed in each relative LinkButton based on its offset from the current page.
The ComputeRowRange function returns a string containing the row numbers associated with a specified page. In this case, it is used to return information that will be displayed in the Current Label control in the middle of the page controls. Once the controls have been updated, the DataView containing the rows to be displayed is assigned to the DataGrid s DataSource property, and DataBind is called to generate the information in the grid.
Initialize a Relative LinkButton
The SetLinkButton routine (see Figure 3) has three parameters: DataView, which contains the rows to be displayed in the grid; an object Reference to the LinkButton control being processed; and the page is associated with that particular LinkButton. The routine begins by hiding the LinkButton if the page associated with it is either the current page or a page outside the range of valid pages in the DataGrid control. If the specified page doesn t meet any of these criteria, it will be displayed and the ComputeRowRange function will be called to determine the proper value to display.
Sub SetLinkButton(dv As DataView, link As LinkButton, page As Integer)
If page = DataGrid1.CurrentPageIndex Then
link.Visible = False
ElseIf page >= DataGrid1.PageCount Then
link.Visible = False
ElseIf Page < 0 Then
link.Visible = False
link.Visible = True
link.Text = ComputeRowRange(dv, page)
Figure 3. The SetLinkButton routine determines whether a link button should be visible based on the page associated with it.
The ComputeRowRange function (see Figure 4) returns the range of rows for a specific page. If the range is invalid, an empty string will be returned. Next, the row number for the first and last pages are computed based on the size of each page. This assumes, however, that the last page is full, so if the last row is larger than the number of rows in the DataView, the number of rows in the DataView is used for the last row. If there is only one row in the range, only the single value is returned; otherwise, first and last are converted to strings and returned.
Function ComputeRowRange(dv As DataView, page as Integer) As String
Dim first As Integer
Dim last As Integer
If page >= DataGrid1.PageCount Then
first = page * DataGrid1.PageSize + 1
last = (page + 1) * DataGrid1.PageSize
If last > dv.Count Then
last = dv.Count
If first = last Then
Return "[" & first.toString & "]"
Return "[" & first.toString & "-" & last.toString & "]"
Figure 4. The ComputeRowRange function determines the first and last row positions for a given page.
First and Last Are Special
The FixupFirst routine (see Figure 5) handles the special case of the first LinkButton. Because I always want the user to be able to return to the first page of the DataGrid, I can t rely on the relative LinkButtons. If the current page is greater than four, the first page will no longer be displayed. This means I must display the LinkButton explicitly.
Sub FixupFirst(dv As DataView)
if DataGrid1.CurrentPageIndex > 4 Then
SetLinkButton(dv, First, 0)
First.Visible = False
if DataGrid1.CurrentPageIndex > 5 Then
FirstGap.Text = "..."
FirstGap.Text = ""
Figure 5. The FixupFirst routine handles the special case when the current page is more than four pages away from the first page.
Then, if the current page is greater than five, there will be a gap between the first page and the first relative LinkButton that points to a page four pages lower than the current page. To indicate the gap, a value of three periods is assigned to the Label control between the first LinkButton and the first relative LinkButton. If there isn t a gap, the Label control will contain an empty string.
This article s sample code is available for download.
Wayne S. Freeze is a full-time computer book author with more than a dozen titles to his credit, including Windows Game Programming with Visual Basic and DirectX (Que) and Unlocking OLAP with SQL Server and Excel 2000 (Hungry Minds). He has more than 25 years of experience using all types of computers, from small, embedded microprocessor control systems to large-scale IBM mainframes. Freeze has a master s degree in management information systems as well as degrees in computer science and engineering. You can visit his Web site at http://www.JustPC.com and send him e-mail at mailto:[email protected]. He loves reading e-mail from his readers, whose ideas, questions, and insights often provide inspiration for future books and articles.
Use the DataGrid control to add flexibility to your data access.