Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / ASP.NET

Playing with the GridView PagerBar

4.74/5 (10 votes)
22 Jun 2007CPOL4 min read 2   662  
Extend GridView.PagerBar while preserving its functionality and add a drop-down to change the page size

Screenshot - gridViewPager.gif

Introduction

If you need table paging functionality, the GridView's PagerBar does a pretty good job for you. Actually, a single click on the AllowPaging property will adorn your table with a nice and fully functional numeric pager. Another click on Pager Settings -> Mode and your pager can change the look 3 times. You don't like any of those looks? Right click the grid, select Edit Template -> PagerTemplate and you are on your own. The problem is that once you template the pager, all of the nice PagerBar functionality is gone. No more clickable page numbers or previous/next buttons; you have to redo them in your template manually.

In this article, we will extend the PagerBar while preserving its functionality. We will add a drop-down that will enable page size changes, the number of rows displayed in one page. This example is simple enough to demonstrate the method and yet it is demanding. Besides extending the look of the PagerBar, we will also have to enable and handle the drop-down's AutoPostback event.

Background

This work was inspired by a post of Phillip Williams' that can be found here. He recommended using the GridView RowCreated event to add a link control to the PagerBar. Very useful information about paging in GridView control can be found in the well-written paper, "Custom Paging in GridView Control" by Francisco Santos Jr.

How we do it

The RowCreated event is raised for each row created in the GridView control. We are interested in the pager row only, so we ignore all other rows. We still do this inside a shared method of our class in order to simplify the code at the user side (and have him pay for the convenience with a few CPU cycles).

VB
If gridRow.RowType <> DataControlRowType.Pager Then Return

Before we insert the page size selector into the PagerBar, we have to make sure that the PagerBar is visible even if the whole table has fewer rows than the current page size. Otherwise, the user will not be able to make the page size smaller. We are currently handling the RowCreated event. As it is too early in the control's life to handle PagerBar visibility, we therefore have to subscribe to the PreRender event of the grid:

VB
Dim enoughRows As Boolean = ( grid.Rows.Count >= MINIMAL_PAGE_SIZE )
If enoughRows Then
    AddHandler grid.PreRender, 
    New EventHandler( AddressOf MakeSurePagerIsVisible)
End If

Once we've grabbed the grid PreRender event, we have to pay attention to the Position settings of the GridView pager. This is because the visibility of the TopPagerRow and BottomPagerRow are handled in GridView independently:

VB
Private Shared Sub MakeSurePagerIsVisible(ByVal sender As Object, 
    ByVal e As System.EventArgs)

    Dim grid As GridView = sender
    Select Case grid.PagerSettings.Position
        Case PagerPosition.Bottom
            grid.BottomPagerRow.Visible = True
        Case PagerPosition.Top
            grid.TopPagerRow.Visible = True
        Case PagerPosition.TopAndBottom
            grid.BottomPagerRow.Visible = True
            grid.TopPagerRow.Visible = True
    End Select

End Sub

Finally, we can add the page size selection drop-down to the pager. A look into the rendered HTML tells us the pager is a table structure that we have to navigate in order to insert a cell at the end of the row. The table cell with the page size selector is created in the CreateSizer function. Once we are in it, we add a label to describe the DropDown. We should not forget to enable AutoPostBack and to signup for the TextChanged event:

VB
sel.AutoPostBack = True
AddHandler sel.TextChanged, 
    New EventHandler( AddressOf PageSizeSelector_Clicked)

Navigation in the pager table happens in the GetPagerTableRow function. This is the code that depends on the way the pager is rendered. This is dangerous because Microsoft might change the way the pager is rendered and then our code would break. Moreover, it hinders our code working with a templated pager if the template does not mimic the generated table structure. Alas, all of those improvements are left to you, dear reader.

The selected page size is stored in a cookie with a unique name that contains the page and control names. Therefore the page and the site can have multiple grids with page length controlled, and all of them can act independently.

Using the code

  1. Add the GridViewPageSize class to your project. A good place to put it is the App_Code folder.
  2. Import the Bsp.Software namespace into your code behind the page with the GridView:
    VB
    Imports Bsp.Software
  3. (Optional) Set the page size from the cookie, if available:
    VB
    Protected Sub GridView_Load(ByVal sender As Object, 
        ByVal e As System.EventArgs) _
        Handles GridView1.Load, GridView2.Load
    
        Dim gv As Control = sender
        If Not gv.Page.IsPostBack Then
            GridViewPageSize.SetPageSize(Me, sender)
        End If
    
    End Sub
  4. Insert the PageSize selector into the pager at the RowCreated event:
    VB
    Protected Sub GridView_RowCreated(ByVal sender As Object, 
        ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) _
        Handles GridView1.RowCreated, GridView2.RowCreated
    
        GridViewPageSize.AddSizerToGridPager(sender, e.Row)
    
    End Sub

History

  • 20 June, 2007: The code and this paper were created and submitted for the CodeProject review.
  • 21 June, 2007: The code was improved thanks to Phillip Williams. The original version did not handle situations when the page refresh event occurred right after the GridView page size changed. The complete PageSizeSelector_Clicked should be re-executed even when the cookie created during the preceding post-back already exists.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)