Wednesday, October 5, 2011

Creating a Custom Pager For an ASP.NET Gridview

In Asp.Net, one of the most often used data controls is the Gridview.  It is the work mule for data display and manipulation in the environment.  This being said, on the basic level it is not very elegant.  However, there are methods available that you (as the developer) can use to improve the eye sore.  In this article, we are going to look at how to improve the look and feel of the pager.  With this example, we will create a pager that is more traditional to the World Wide Web.
The Setup:
(This article assumes that you have a working basic knowledge on how to add a Gridview to your project and have already done so)
First things first, we’ll need to enable paging in our Gridview.  We do this with the AllowPaging Property of the Gridview:
<asp:GridView ID="gdvMessages" runat="server" AutoGenerateColumns="false" 
  BorderWidth="0" ShowHeader="false" AllowPaging="true" PageSize="6">

By setting our PageSize property we are limiting the amount of records returned per page.
Next we have to set our PagerTemplate.  This tells the Gridview how we would like to display our new pager.  In this example we are simply creating a table, and in that table creating a placeholder.  This placeholder will hold the controls we will create programmatically to display the relevant page information:
<PagerTemplate>
  <table>
    <tr>
      <td>
        <asp:PlaceHolder ID="phPager" runat="server"></asp:PlaceHolder>
      </td>
    </tr>
  </table>
</PagerTemplate>
As you can see, it is a simple table with a placeholder control.
Now that we have setup the HTML to control our pager, we need to populate it with relevant data in our code behind.
The first order of business is to create a Sub that is only available to the relevant page.  Obviously, the page where the Gridview exists is the appropriate one.  We will call this Sub ApplyPaging.
Private Sub ApplyPaging()
After we create the Sub, we will need to create som controls that will populate the pager.  Our first order of business is to define the row of the Gridview we want to work with.
Dim row As GridViewRow = gdvMessages.BottomPagerRow
This creates a variable of GridViewRow which is available to us through the inheritance of System.Web.UI.Page.
Next we create the controls.
Dim ph As PlaceHolder
Dim lnkPaging As LinkButton
Dim lnkFirstPage As LinkButton
Dim lnkPrevPage As LinkButton
Dim lnkNextPage As LinkButton
Dim lnkLastPage As LinkButton
This sets up the buttons we want to appear on the Pager.
Now we will begin to populate the buttons.
lnkFirstPage = New LinkButton()
lnkFirstPage.Text = "<b>" & Server.HtmlEncode("<<First") & "</b>"
lnkFirstPage.Width = Unit.Pixel(50)
lnkFirstPage.CommandName = "Page"
lnkFirstPage.CommandArgument = "first"
We instantiate the lnkFirstPage control as a New LinkButton.  Then we set its Text property along with a couple other attributes that control how the LinkButton interacts with the Gridview.
lnkPrevPage = New LinkButton()
lnkPrevPage.Text = "<b>" & Server.HtmlEncode("<Prev") & "</b>"
lnkPrevPage.Width = Unit.Pixel(50)
lnkPrevPage.CommandName = "Page"
lnkPrevPage.CommandArgument = "prev"
ph = DirectCast(row.FindControl("phPager"), PlaceHolder)
ph.Controls.Add(lnkFirstPage)
ph.Controls.Add(lnkPrevPage)
We perform the same step with the lnkPrevPage button, and then add the controls to the PlaceHolder on the Gridview.
If gdvMessages.PageIndex = 0 Then
  lnkFirstPage.Enabled = False
  lnkPrevPage.Enabled = False
End If
Here we are testing to see if we are at the 1st page.  If we are there is no need to enable the First and Previous LinkButton controls.
Then we just repeat the steps for the Next and Last LinkButton controls.
lnkNextPage = New LinkButton()
lnkNextPage.Text = "<b>" & Server.HtmlEncode("Next>") & "</b>"
lnkNextPage.Width = Unit.Pixel(50)
lnkNextPage.CommandName = "Page"
lnkNextPage.CommandArgument = "next"
lnkLastPage = New LinkButton()
lnkLastPage.Text = "<b>" & Server.HtmlEncode("Last>>") & "</b>"
lnkLastPage.Width = Unit.Pixel(50)
lnkLastPage.CommandName = "Page"
lnkLastPage.CommandArgument = "last"
ph = DirectCast(row.FindControl("phPager"), PlaceHolder)
ph.Controls.Add(lnkNextPage)
ph = DirectCast(row.FindControl("phPager"), PlaceHolder)
ph.Controls.Add(lnkLastPage)
If gdvMessages.PageIndex = gdvMessages.PageCount - 1 Then
  lnkNextPage.Enabled = False
  lnkLastPage.Enabled = False
End If
Finally, we need to close the Sub.
End Sub

Now, to trigger the ApplyPager Sub we will add a call to the DataBound trigger of the Gridview.
Protected Sub gdvMessages_DataBound(ByVal sender As Object
  ByVal e As System.EventArgsHandles gdvMessages.DataBound
    ApplyPaging()
End Sub
We also need to trigger the Sub if it is a Postback in the Page_Load Sub for the page.
If IsPostBack Then
  ApplyPaging()
End If
Now we have a Pager that has been extended past the typical 1 2 3 4 display.
If we wanted to extend it further we can add a Label control to the page and display to the user what page they are viewing (I typically add this to just above the Gridview at the top).
<asp:Label ID="lblPagerCount" runat="server" Text="" />
Now that we have a Label control on the page.  We need to create another Sub to populate it.
Private Sub ApplyPageCounter()
We need to populate the Label control in the Sub.
Dim currentPage As Integer = gdvMessages.PageIndex + 1
Dim totalPages As Integer = gdvMessages.PageCount
lblPagerCount.Text = String.Format("Page {0} of {1}", currentPage, totalPages)
Finally, close the Sub.
End Sub
We need to call our new Sub from some triggers, so we add the ApplyPageCounter to the DataBound trigger for the Gridview control.
Protected Sub gdvMessages_DataBound(ByVal sender As Object
  ByVal e As System.EventArgsHandles gdvMessages.DataBound
    ApplyPaging()
    ApplyPageCounter()
End Sub
We also need to add it to the Postback in the Sub Page_Load
If IsPostBack Then
  ApplyPaging()
  ApplyPageCounter()
End If
Now we have completely changed the way the Gridview Pager represents itself.  In this case, we made a Page Counter (for the Gridview) completely outside the Gridview itself.  The Page Counter can be placed in any area on the Page (I would highly suggest you put it in or around the Gridview to alleviate confusion).

Happy .Netting… Saleh

No comments:

Post a Comment