asp.netNOW Q&A
LANGUAGES: VB
TECHNOLOGIES: DataGrids | Paging
Page DataGrids and Search on One Page
Learn the proper way to page a DataGrid and reset it for new data.
By Josef Finsel
Q: I have a DataGrid paging problem I'm unable to solve. Essentially, I don't know how to reset the current page index. For example, suppose I have a DataGrid with 84 rows and I'm looking at the first page. If I go to page 2 and load the grid with a new text search that returns only one page in the grid, I get an error because the currentpageindex can't find its way on the new currentpageindex.
A: This is one of those problems folks really don't like to deal with in demos because, although it's easy enough to work around, it can be a pain. That's why most paging grid demos are separate from the routines that fill them. One workaround is to create two separate pages - one containing the DataGrid and one containing the search code. But because that doesn't work every time, you need to create a paged DataGrid with the search at the top, then look at what you need to do to avoid the errors.
To demonstrate, I'll show you a working code sample from my Web site (you can see the code at http://www.reluctantdba.com/QuoteMaintenance/SearchQuotes.aspx). Take a look at the HTML that will contain a simple table with the search in the top row and the DataGrid in the bottom row (you can download all of this article's code):
<form id="QuoteForm" method="post" runat="server">
<table border="2">
<tr>
<td vAlign="top">Search quotes that include:</td>
<td><asp:textbox id="txtSearch" style="Z-INDEX: 102" runat="server" Width="275px" MaxLength="25" tabIndex="3"></asp:textbox>
<asp:button id="cmdSearch" runat="server" Text="Search!" tabIndex="4"></asp:button>
</td>
</tr>
<tr>
<td colspan="2"><asp:label id="lblResults" style="Z-INDEX: 107" runat="server" Font-Size="Medium" Font-Bold="True"></asp:label><br>
<asp:datagrid id="dgQuotes" style="Z-INDEX: 101" runat="server" OnPageIndexChanged="dgQuotes_Page" AllowPaging="True" Height="20px" Width="100%">
<AlternatingItemStyle BorderWidth="1px" ForeColor="#FFFFC0" BorderStyle="Solid" BorderColor="Black" VerticalAlign="Top" BackColor="DodgerBlue"></AlternatingItemStyle>
<ItemStyle BorderWidth="1px" BorderStyle="Solid" BorderColor="Black" VerticalAlign="Top"></ItemStyle>
<HeaderStyle Font-Bold="True" ForeColor="#FFFFC0" BorderStyle="Solid" BorderColor="White" BackColor="#400000"></HeaderStyle>
<PagerStyle NextPageText="Next" PrevPageText="Last" Mode="NumericPages"></PagerStyle>
</asp:datagrid>
</td>
</tr>
</table>
</form>
As you can see, there's nothing too exciting in the HTML. The key to making this work is in the code behind. Note that, in order for the code to work, you need a Web reference to http://www.reluctantdba.com/WebQuotes. The key here is in the code behind for the search button and the paging section:
Private Sub cmdSearch_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles cmdSearch.Click
Dim qt As New com.reluctantdba.www.WebQuotes()
Dim dv As DataView = New _
DataView(qt.SearchQuotes("aspnetpro", "password", txtSearch.Text).Tables(0))
dgQuotes.DataSource = dv
dgQuotes.CurrentPageIndex = 0
dgQuotes.DataBind()
lblResults.Text = "Results of Search"
End Sub
Sub dgQuotes_Page(ByVal source As Object, ByVal e As _
System.Web.UI.WebControls.DataGridPageChangedEventArgs) Handles dgQuotes.PageIndexChanged
Dim qt As New com.reluctantdba.www.WebQuotes()
Dim dv As DataView = New _
DataView(qt.SearchQuotes("aspnetpro", "password", txtSearch.Text).Tables(0))
dgQuotes.DataSource = dv
dgQuotes.CurrentPageIndex = e.NewPageIndex
dgQuotes.DataBind()
End Sub
The key here is that the search section resets the current page index to 0. If you don't do this separately from the paging command, you run into the CurrentPageIndex must be >= 0 and < the PageCount error because of the interconnectedness of the grid and the data. When the PageIndexChanged event gets called, the grid attempts to set to the current page with the existing data set before it processes the request to set the page to 0. And, if you've replaced the data set with a smaller one, you get the error even though you haven't yet bound it to the grid. By separating the two functions, everything works.
For a more comprehensive look at data paging, check out Dino Esposito's article, Provide Pagination for Your DataLists.
Keep your ASP.NET questions coming to me at [email protected].
The sample code in this article is available for download.
Josef Finsel is a software consultant with a global consulting firm and specializes in .NET and SQL Server. He has published a number of VB, .NET, and SQL Server-related articles, and when he isn't hanging around the aspnetpro forums, you can find him working on the syntax for FizzBin.NET, a programming language that works the way programmers have always suspected. He's also author of The Handbook for Reluctant Database Administrators (Apress).