1.7. Adding Next/Previous Navigation to a DataGrid

Problem

You need to display data from a database in a table, but the database has more rows than can fit on a single page so you want to use next/previous buttons for navigation.

Solution

Use a DataGrid control, enable its built-in pagination features, and then bind the data to it.

Add a DataGrid control to the .aspx file, and use its AllowPaging and other related attributes to enable pagination.

In the code-behind class for the page, use the .NET language of your choice to:

  1. Create a routine that binds a DataSet to the DataGrid in the usual fashion.

  2. Create an event handler that performs the page navigation—for example, one that handles the PageIndexChanged event for the DataGrid—and rebinds the data.

Figure 1-6 shows the appearance of a typical DataGrid within a browser with next/previous navigation. Example 1-17 through Example 1-19 show the .aspx and code-behind files for an application that produces this result.

DataGrid with next/previous navigation output

Figure 1-6. DataGrid with next/previous navigation output

Discussion

The DataGrid control includes the ability to perform pagination of the data that is displayed in the grid, and using the built-in pagination requires very little code. Pagination is enabled and configured by the attributes of the DataGrid element:

  AllowPaging="True"
  PageSize="5"
  PagerStyle-Mode="NextPrev"
  PagerStyle-Position="Bottom"
  PagerStyle-HorizontalAlign="Center"
  PagerStyle-NextPageText="Next"
  PagerStyle-PrevPageText="Prev">

Setting the AllowPaging attribute to True enables paging for the DataGrid, and the PageSize attribute defines the number of rows that will be displayed in a single page. Setting the PageStyle-Mode attribute to NextPrev enables the output of the Next/Prev controls (see Recipe 1.9 for other uses of this attribute).

The remaining attributes define how the pagination controls look. PageStyle-Position defines the location of the Next/Prev controls. Valid values include Bottom, Top, and TopAndBottom. PagerStyle-HorizontalAlign defines the horizontal positioning of the Next/Prev controls. Valid values include Left, Center, Right, and NotSet. NotSet is effectively the same as Left because Left is the default.

PagerStyle-NextPageText defines the text to output for the next page navigation control, and PagerStyle-PrevPageText defines the text to output for the previous page navigation.

Tip

The PagerStyle-NextPageText and PagerStyle-PrevPageText attribute values can include HTML to format the text of the controls. Virtually any HTML can be used, including image tags. If you change the values of the two text attributes, the Next/Prev controls will be output, as shown in Figure 1-7.

PagerStyle-NextPageText=
  "<img src='images/buttons/button_next.gif'
        border='0'>"
PagerStyle-PrevPageText=
  "<img src='images/buttons/button_prev.gif'
        border='0'>">
DataGrid output using image tags for next/previous controls

Figure 1-7. DataGrid output using image tags for next/previous controls

The bindData routine, shown in the code-behind in Example 1-18 (VB) and Example 1-19 (C#), performs the data binding. This routine provides the typical binding of a dataset to the DataGrid. No additional code is required in this routine to support the default pagination.

The dgBooks_PageIndexChanged event handler provides the code required to perform the page navigation. The new page number to display is passed in the event arguments (e). The CurrentPageIndex property of the DataGrid must be set to the passed value, and the data must be rebound to the DataGrid.

Tip

The default pagination code shown in this recipe can be very inefficient when used with data containing a large number of rows. By default, all of the data for a query is returned and used to populate the DataSet. When the query returns a relatively small set of data (less than 100 rows and a small number of columns), the pagination shown in this recipe is adequate for most applications. If your query returns a million rows, the performance of your application will be unacceptable. See Recipe 1.10 for a more efficient approach to the pagination of large datasets.

See Also

Recipe 1.8, Recipe 1.9, and Recipe 1.10 for other examples of pagination

Example 1-17. DataGrid with next/previous navigation (.aspx)

<%@ Page Language="vb" AutoEventWireup="false" 
         Codebehind="CH01DatagridWithNextPrevNavVB1.aspx.vb" 
         Inherits="ASPNetCookbook.VBExamples.CH01DatagridWithNextPrevNavVB1" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
  <head>
    <title>Datagrid With Text For Next/Prev Navigation</title>
    <link rel="stylesheet" href="css/ASPNetCookbook.css">
  </head>
  <body leftmargin="0" marginheight="0" marginwidth="0" topmargin="0">
    <form id="frmData" method="post" runat="server">
      <table width="100%" cellpadding="0" cellspacing="0" border="0">
        <tr>
          <td align="center">
            <img src="images/ASPNETCookbookHeading_blue.gif">
          </td>
        </tr>
        <tr>
          <td class="dividerLine">
            <img src="images/spacer.gif" height="6" border="0"></td>
        </tr>
      </table>
      <table width="90%" align="center" border="0">
        <tr>
          <td><img src="images/spacer.gif" height="10" border="0"></td>
        </tr>
        <tr>
          <td align="center" class="PageHeading">
            DataGrid Using Text For Next/Previous Navigation (VB)
          </td>
        </tr>
        <tr>
          <td><img src="images/spacer.gif" height="10" border="0"></td>
        </tr>
        <tr>
          <td align="center">
            <asp:DataGrid 
                                id="dgBooks" 
                                runat="server" 
                                BorderColor="000080" 
                                BorderWidth="2px"
                                AutoGenerateColumns="False"
                                width="100%"
                                AllowPaging="True"
                                PageSize="5"
                                PagerStyle-Mode="NextPrev"
                                PagerStyle-Position="Bottom"
                                PagerStyle-HorizontalAlign="Center" 
                                PagerStyle-NextPageText="Next"
                                PagerStyle-PrevPageText="Prev">

                                <HeaderStyle HorizontalAlign="Center" 
                                             ForeColor="#FFFFFF" 
                                             BackColor="#000080" 
                                             Font-Bold=true
                                             CssClass="TableHeader" /> 

                                <ItemStyle BackColor="#FFFFE0" 
                                           cssClass="TableCellNormal" />

                                <AlternatingItemStyle BackColor="#FFFFFF" 
                                                      cssClass="TableCellAlternating" />
                                

                                <Columns>
                                  <asp:BoundColumn HeaderText="Title" DataField="Title" />
                                  <asp:BoundColumn HeaderText="ISBN" DataField="ISBN" 
                                                   ItemStyle-HorizontalAlign="Center" />
                                  <asp:BoundColumn HeaderText="Publisher" DataField="Publisher"
                                                   ItemStyle-HorizontalAlign="Center" />
                                </Columns>
                              </asp:DataGrid>
          </td>
        </tr>
      </table>
    </form>
  </body>
</html>

Example 1-18. DataGrid with next/previous navigation code-behind (.vb)

Option Explicit On 
Option Strict On
'-----------------------------------------------------------------------------
'
'   Module Name: CH01DatagridWithNextPrevNavVB1.aspx.vb
'
'   Description: This class provides the code behind for
'                CH01DatagridWithNextPrevNavVB1.aspx
'
'*****************************************************************************
Imports Microsoft.VisualBasic
Imports System.Configuration
Imports System.Data
Imports System.Data.OleDb

Namespace ASPNetCookbook.VBExamples
  Public Class CH01DatagridWithNextPrevNavVB1
    Inherits System.Web.UI.Page

    'controls on form
    Protected WithEvents dgBooks As System.Web.UI.WebControls.DataGrid

    '*************************************************************************
    '
    '   ROUTINE: Page_Load
    '
    '   DESCRIPTION: This routine provides the event handler for the page load
    '                event.  It is responsible for initializing the controls 
    '                on the page.
    '-------------------------------------------------------------------------
    Private Sub Page_Load(ByVal sender As System.Object, _
                          ByVal e As System.EventArgs) _
            Handles MyBase.Load

      If (Not Page.IsPostBack) Then
        bindData( )
      End If
    End Sub  'Page_Load

    '*************************************************************************
    '
    '   ROUTINE: dgCustomers_PageIndexChanged
    '
    '   DESCRIPTION: This routine provides the event handler for the page 
    '                index changed event of the datagrid.  It is responsible  
    '                for setting the page index from the passed arguments and
    '                rebinding the data.
    '-------------------------------------------------------------------------
    Private Sub dgBooks_PageIndexChanged(ByVal source As Object, _
          ByVal e As System.Web.UI.WebControls.DataGridPageChangedEventArgs) _
          Handles dgBooks.PageIndexChanged

      'set new page index and rebind the data
                        dgBooks.CurrentPageIndex = e.NewPageIndex
                        bindData( )
    End Sub  'dgCustomers_PageIndexChanged

    '*************************************************************************
    '
    '   ROUTINE: bindData
    '
    '   DESCRIPTION: This routine queries the database for the data to 
    '                displayed and binds it to the datagrid
    '-------------------------------------------------------------------------
    Private Sub bindData( )
      Dim dbConn As OleDbConnection
      Dim da As OleDbDataAdapter
      Dim dSet As DataSet
      Dim strConnection As String
      Dim strSQL As String

      Try
        'get the connection string from web.config and open a connection 
                          'to the database
                          strConnection = _
                              ConfigurationSettings.AppSettings("dbConnectionString")
                          dbConn = New OleDb.OleDbConnection(strConnection)
                          dbConn.Open( )

                          'build the query string and get the data from the database
                          strSQL = "SELECT Title, ISBN, Publisher " & _
                                   "FROM Book " & _
                                   "ORDER BY Title"
                          da = New OleDbDataAdapter(strSQL, dbConn)
                          dSet = New DataSet
                          da.Fill(dSet)

                          'set the source of the data for the datagrid control and bind it
                          dgBooks.DataSource = dSet
                          dgBooks.DataBind( )

      Finally
        'cleanup
        If (Not IsNothing(dbConn)) Then
          dbConn.Close( )
        End If
      End Try
    End Sub  'bindData
  End Class  'CH01DatagridWithNextPrevNavVB1
End Namespace

Example 1-19. DataGrid with next/previous navigation code-behind (.cs)

//----------------------------------------------------------------------------
//
//   Module Name: CH01DatagridWithNextPrevNavCS1.aspx.cs
//
//   Description: This class provides the code behind for
//                CH01DatagridWithNextPrevNavCS1.aspx
//
//****************************************************************************
using System;
using System.Configuration;
using System.Data;
using System.Data.OleDb;
using System.Web.UI.WebControls;

namespace ASPNetCookbook.CSExamples
{
  public class CH01DatagridWithNextPrevNavCS1 : System.Web.UI.Page
  {
    // controls on form
    protected System.Web.UI.WebControls.DataGrid dgBooks;

    //************************************************************************
    //
    //   ROUTINE: Page_Load
    //
    //   DESCRIPTION: This routine provides the event handler for the page
    //                load event.  It is responsible for initializing the
    //                controls on the page.
    //
    //------------------------------------------------------------------------
    private void Page_Load(object sender, System.EventArgs e)
    {
      // wire in the page index changed event
                        this.dgBooks.PageIndexChanged += 
                          new DataGridPageChangedEventHandler(this.dgBooks_PageIndexChanged);

      if (!Page.IsPostBack)
      {
        bindData( );
      }
    }  // Page_Load
    //************************************************************************
    //
    //   ROUTINE: dgCustomers_PageIndexChanged
    //
    //   DESCRIPTION: This routine provides the event handler for the page
    //                index changed event of the datagrid.  It is responsible
    //                for setting the page index from the passed arguments
    //                and rebinding the data.
    //
    //------------------------------------------------------------------------
    private void dgBooks_PageIndexChanged(Object source,
      System.Web.UI.WebControls.DataGridPageChangedEventArgs e)
    {
      // set new page index and rebind the data
                        dgBooks.CurrentPageIndex = e.NewPageIndex;
                        bindData( );
    }  // dgCustomers_PageIndexChanged

    //************************************************************************
    //
    //   ROUTINE: bindData
    //
    //   DESCRIPTION: This routine queries the database for the data to
    //                displayed and binds it to the repeater
    //
    //------------------------------------------------------------------------
    private void bindData( )
    {
      OleDbConnection dbConn = null;
      OleDbDataAdapter da = null;
      DataSet dSet = null;
      String strConnection = null;
      String strSQL =null;

      try
      {
        // get the connection string from web.config and open a connection 
                          // to the database
                          strConnection = 
                              ConfigurationSettings.AppSettings["dbConnectionString"];
                          dbConn = new OleDbConnection(strConnection);
                          dbConn.Open( );

                          // build the query string and get the data from the database
                          strSQL = "SELECT Title, ISBN, Publisher " +
                                   "FROM Book " +
                                   "ORDER BY Title";
                          da = new OleDbDataAdapter(strSQL, dbConn);
                          dSet = new DataSet( );
                          da.Fill(dSet, "Table");

                          // set the source of the data for the datagrid control and bind it
                          dgBooks.DataSource = dSet;
                          dgBooks.DataBind( );
      }  // try

      finally
      {
        //clean up
        if (dbConn != null)
        {
          dbConn.Close( );
        }
      }  // finally
    }  // bindData
  }  // CH01DatagridWithNextPrevNavCS1
}

Get ASP.NET Cookbook now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.