1. Original Entry + Comments2. Write a Comment3. Preview Comment
New comments for this entry are disabled.


January 13, 2006  |  Customizing the GridView Pager  |  8654 hit(s)

I mentioned that I was using a GridView control with paging, and I wanted to add a "Last" link to it that would always jump to the last page. This was one a them learning experiences.

Years ago I attended an excellent user group presentation in which someone (forgot who, dang) showed some neat tricks for manipulating the links in a DataGrid pager. That looked like fun, so in one of my apps I added code that would highlight the current page among the page links. Here's the code (idea lifted from someone smarter than me, I'll note again):
Sub DataGrid1_ItemCreated(sender As Object, e As DataGridItemEventArgs)
If e.Item.ItemType = ListItemType.Pager Then
Dim i As Integer
For i = 0 to e.Item.Cells(0).Controls.Count - 1
If TypeOf( e.Item.Cells(0).Controls(i) ) Is Label Then
Dim l As Label = e.Item.Cells(0).Controls(i)
l.backcolor = System.Drawing.Color.violet
l.font.name = "Verdana"
l.font.bold = True
l.forecolor = System.Drawing.Color.White
l.text = " " & l.text & " " ' Padding
End If
Next i
End If
End Sub
When a grid row is created, the code first sees if this is the pager row. If so, it walks the controls in the pager cell. The current page will be displayed using a Label control; other pages are displayed as LinkButton controls. So when the code finds a Label control, it tarts it all up with colors and stuff.

The salient point here is this: in the DataGrid contol, the pager row consists of a single cell with a colspan. Inside that single cell are the controls for paging. In the code, e.Item.Cells(0) contains a collection of controls that are accessible at ItemCreated time. I figured that the GridView control would work the same. It doesn't, not quite.

In the GridView control, at RowCreated time, e.Rows.Cells(0).Controls contains but a single control, no matter how many page numbers the grid is displaying. One control!? WTF? And even weirder, that single control was of type System.Web.UI.WebControls.PagerTable, and I'll just save you the trouble and tell you now that that type is quite undocumented.

Google found me a forum entry that clarified this. PagerTable is an internal class that you can't access directly, but you can cast it to a normal ASP.NET Table control. There's a single row (TableRow control) in the table, and each page number is in its own cell (TableCell). If you want to manipulate the numbers, you drill into the cells; in the cells are controls of type DataControlPagerLinkButton. These can be cast[ed] to a LinkButton if you need to mess with them directly.

In my case, I wanted to add a link that would take me to the last page. So I had to add a TableCell control and within the cell, add a LinkButton and lash up a handler for its Click event. This is the code I ended up with:
Protected Sub GridView1_RowCreated(ByVal sender As Object, _
ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs)
If e.Row.RowType = DataControlRowType.Pager Then
If GridView1.PageIndex < GridView1.PageCount - 1 Then
Dim pagerCell As New TableCell
Dim lastLink As New LinkButton
lastLink.Text = "[last]"
AddHandler lastLink.Click, AddressOf GoToLastPage


pagerCell.Controls.Add(lastLink)


Dim pagerTable As Table = CType(e.Row.Cells(0).Controls(0), Table)
pagerTable.Rows(0).Cells.Add(pagerCell)
End If
End If
End Sub
And here's the handler for the button:
Protected Sub GoToLastPage(ByVal Sender As Object, _
ByVal e As EventArgs)
GridView1.PageIndex = GridView1.PageCount - 1
End Sub




Frank   08 Feb 06 - 3:53 AM

Hi Mike,

Its all not that hard, look at this item I posted at my blog

Extending GridView Pager with pagertemplate:

http://dotnetpret.blogspot.com/2006/02/extending-gridview-pager-with.html

including samplecode

Cheers,
Frank


 
mike   08 Feb 06 - 9:16 AM

Cool approach. I do have to note that I didn't find it hard to mess around with the pager, once -- aha, there's the rub -- I figured out how it was structured. Your approach is way flexible, tho -- particularly suitable to changing the whole thing on the fly. (?)

 
Dnyaneshwar   13 Apr 07 - 8:27 AM

Hi i Goes through tour code, i am just makeing one point here.
You had assigned handler "Protected Sub listManufacturers_SelectedIndexChanged(ByVal sender As Object, _ ByVal e As System.EventArgs)"
in that case the "Sender" itself is a DropDownlist then why you are using findControl Method ?
Dim listManufacturers as DropDownList = Ctype(sender,DropDownList)
this will give you stright way the DropDownList.

Please correct me if i am wrong.


 
mike   13 Apr 07 - 9:12 AM

@Dyaneshwar -- you are correct. I've updated the entry (http://mikepope.com/blog/DisplayBlog.aspx?permalink=1709).