Pages

Friday, November 11, 2011

ASP.NET GridView with Custom Paging UI


The GridView is a great web control when you want to display data from the database. Out of the box it has built-in paging, sorting and a multitude of events that you can control. Recently I thought about the paging aspect of the control and thought about how you could display the page numbers as something other than numbers, such as letters. Well here’s the answer! This code has not been requested by any of my customers but I thought it would be cool to try it out!
The trick to making this work is once the data has been bound to the GridView, you need to create the paging manually. This can be achieved by getting a reference to the BottomPagerRow property. The BottomPagerRow property represents the bottom pager row in a GridView. Once you have that reference you can create custom paging. For this example I’ll be connecting to the Northwind database. If you don’t have a copy of it, you can go here to download it.
To begin with open Visual Studio 2008 and choose File > New > Web > ASP.NET Web Application. 
Open the Default.aspx page and add a GridView control to the page. Click on the Smart Tag and in the Choose Data Source option choose <New data source...>
 
Choose_NewDataSource
 
Choose Database as the data source and let the name as chosen by Visual Studio. 
 
Database
 
Click OK. In the following screen choose your connection string and click Next:
 
DataConnection
 
After that select CustomerID, CompanyName, ContactName, ContactTitle, Address and City from the Customers table and click Next and then Finish after that:
 
Configure_Select_Statement
 
Now that after we have defined the data, we need to open the Default.aspx page and add a PagerTemplate to the GridView. The PagerTemplate allows you to customise the look and feel of the paging that will be displayed. Your code for the GridView will look like the following:
 
<asp:GridView ID="GridView1" runat="server" AllowPaging="True" OnPageIndexChanging="GridView1_PageIndexChanging"
        OnDataBound="GridView1_DataBound" AutoGenerateColumns="False" DataKeyNames="CustomerID"
        DataSourceID="SqlDataSource1">
        <Columns>
            <asp:BoundField DataField="CustomerID" HeaderText="CustomerID" ReadOnly="True" SortExpression="CustomerID" />
            <asp:BoundField DataField="CompanyName" HeaderText="CompanyName" SortExpression="CompanyName" />
            <asp:BoundField DataField="ContactName" HeaderText="ContactName" SortExpression="ContactName" />
           <asp:BoundField DataField="ContactTitle" HeaderText="ContactTitle" SortExpression="ContactTitle" />
            <asp:BoundField DataField="Address" HeaderText="Address" SortExpression="Address" />
            <asp:BoundField DataField="City" HeaderText="City" SortExpression="City" />
        </Columns>
        <PagerTemplate>
            <table width="100%">
                <tr>
                    <td style="text-alignright">
                        <asp:PlaceHolder ID="PlaceHolder1" runat="server" />
                    </td>
                </tr>
            </table>
        </PagerTemplate>
    </asp:GridView>
 
In the code above I have created a PagerTemplate. Inside I have created a simple HTML table that contains a PlaceHolder control. I am using aPlaceHolder because I want to dynamically add LinkButton controls to the PagerTemplate.
 
That’s it for the UI. Now we need to create the code that runs our custom paging. There are two events you need to hook into to make this work. They are the DataBound and the PageIndexChanging events. Handling the PageIndexChanging event is critical when you’re creating custom paging. Without it theGridView will not know which page to display to the user and throw an exception. Below is the code that creates and handles the paging:
 
C#
 
protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
{           
      GridView1.PageIndex = e.NewPageIndex;                     
}
 
protected void GridView1_DataBound(object sender, EventArgs e)
{  
      SetPaging();
}
 
private void SetPaging()
{
      GridViewRow row = GridView1.BottomPagerRow;
      int alphaStart = 65;
           
      for (int i = 1; i < GridView1.PageCount; i++)
      {               
            LinkButton btn = new LinkButton();
            btn.CommandName = "Page";
            btn.CommandArgument = i.ToString();
 
            if (i == GridView1.PageIndex + 1)
            {
                  btn.BackColor = Color.BlanchedAlmond;
            }
 
            btn.Text = Convert.ToChar(alphaStart).ToString();
            btn.ToolTip = "Page " + i.ToString();
            alphaStart++;
PlaceHolder place = row.FindControl("PlaceHolder1"as PlaceHolder;
            place.Controls.Add(btn);
 
            Label lbl = new Label();
            lbl.Text = " ";
            place.Controls.Add(lbl);
      }
}
 
VB.NET
 
Protected Sub GridView1_PageIndexChanging(ByVal sender As ObjectByVal e As GridViewPageEventArgs)
      GridView1.PageIndex = e.NewPageIndex
End Sub
 
Protected Sub GridView1_DataBound(ByVal sender As ObjectByVal e As EventArgs)
      SetPaging()
End Sub
 
Private Sub SetPaging()
      Dim row As GridViewRow = GridView1.BottomPagerRow
       Dim alphaStart As Integer = 65
 
       For i As Integer = 1 To GridView1.PageCount - 1
             Dim btn As New LinkButton()
                  btn.CommandName = "Page"
                  btn.CommandArgument = i.ToString()
 
                  If i = GridView1.PageIndex + 1 Then
                        btn.BackColor = Color.BlanchedAlmond
                  End If
 
                  btn.Text = Convert.ToChar(alphaStart).ToString()
                  btn.ToolTip = "Page " & i.ToString()
                  alphaStart += 1
Dim place As PlaceHolder = TryCast(row.FindControl("PlaceHolder1"), PlaceHolder)
                  place.Controls.Add(btn)
 
                  Dim lbl As New Label()
                  lbl.Text = " "
                  place.Controls.Add(lbl)
       Next i
End Sub
 
The main piece of code is the SetPaging method. This method is called once the GridView has been data bound. Firstly the code gets a reference to the paging row by the BottomPagerRow property. Next a LinkButton is created. This is created because the GridView will accept special parameters via theCommandName and CommandArgument properties. The CommandName must be set to Page but the CommandArgument can be one of the following values:
 
  • Integer Value – Navigates to the page number
  • Next – Navigates to the next page
  • Prev - Navigates to the previous page
  • Last – Navigates to the last page
  • First – Navigates to the first page
 
I am setting the CommandArgument to the index of the row. This way whenever a user clicks pages through the data, the GridView will know which page to display. And finally instead of showing numbers I am displaying letters of the alphabet. The letter A starts at 65, so I have created a variable called alphaStart to 65. To turn a number into an ascii value you can use the Convert.ToChar(alphaStart).ToString() code. For each row in the GridView I am incrementing the value of alphaStart, so that 1 will equal A, 2 will equal B etc. Once the LinkButton has been created, it is added to the PlaceHoldercontrols collection. The result is paging with letters.
 
Query_Result
 
This example might not be used in the real world, but I found it fun trying to work out how to make this work. Hopefully you’ll find some useful bits of information in here too.

Note: If you want to see other tips and tricks related to GridView Paging, check out another article by Suprotim Some Tips and Tricks while Using ASP.NET GridView Paging

The entire source code of this article can be downloaded from here

No comments:

Post a Comment