Monday, September 22, 2008

A comprehensive and generic ListView Pager.

Here is a comprehensive List View Pager, for your convenience. Just copy the code into your markup and the functions into your code behind It is absolutely generic, you can have any number of listviews in your markup and they can all use the one set of pager functions. That's double plus generic!

Please forgive Bloggers horrendous formatting.

First, A checkbox to switch Paging on and off, if you like. Put it in your layout template, I recommend in the first column header of your view which is usually the one above your edit and delete buttons:

<asp:checkbox id="AllowPaging" runat="server" autopostback="True" oncheckedchanged="AllowPaging_CheckedChanged" text=" Paging" Backcolor="Transparent" bordercolor="Transparent" checked="true">


Next, the pager Template itself. I put this as the last row in my Listview Layout template:
<tr runat="server" id="PagerRow">
<td id="Td2" runat="server" class="lvPagerow ">

<asp:DataPager ID="lvPager" runat="server">

<Fields>

<asp:TemplatePagerField OnPagerCommand="lvPager_OnPagerCommand">

<PagerTemplate>

<asp:Panel ID="pnlPager" runat="server">

<asp:ImageButton ID="ImageButton1" runat="server" ImageUrl="~/images/first.gif" CommandArgument="First" CommandName="Page" />

<asp:ImageButton ID="ImageButton2" runat="server" ImageUrl="~/images/prev.gif" CommandArgument="Prev" CommandName="Page" />

Page

<asp:DropDownList ID="ddlPages" runat="server" AutoPostBack="True" OnSelectedIndexChanged="Pages_SelectedIndexChanged" OnDataBinding="ddlPages_OnDataBinding">

</asp:DropDownList>

of

<asp:Label ID="lblPageCount" runat="server" Text='<%# System.Math.Ceiling(Container.TotalRowCount / Container.PageSize) %>'></asp:Label>
<asp:ImageButton ID="ImageButton3" runat="server" ImageUrl="~/images/next.gif" CommandArgument="Next" CommandName="Page" />

<asp:ImageButton ID="ImageButton4" runat="server" ImageUrl="~/images/last.gif" CommandArgument="Last" CommandName="Page" />

</asp:Panel>

</PagerTemplate>

</asp:TemplatePagerField>

</Fields>

</asp:DataPager>

</td>

</tr>

Add the following Event binding in your ListView declaration:
OnDataBound="ListView_DataBound"
And Now, the functions that do the work in code behind:
Protected Sub AllowPaging_CheckedChanged(ByVal sender As Object, ByVal e As System.EventArgs)
Dim lvPager As DataPager = CType(sender.bindingcontainer, ListView).FindControl("lvPager")

Dim chkPaging As CheckBox = CType(sender, CheckBox)

lvPager.Visible = Not lvPager.Visible

CType(sender.BindingContainer, ListView).DataBind()

End Sub

Protected Sub Pages_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs)
Dim ddlPages As DropDownList = CType(sender, DropDownList)

Dim lvPager As DataPager = CType(sender.BindingContainer, DataPager)

lvPager.SetPageProperties((ddlPages.SelectedValue - 1) * lvPager.PageSize, lvPager.PageSize, True)


End Sub

Protected Sub ddlPages_OnDataBinding(ByVal sender As Object, ByVal e As System.EventArgs)
Dim lvPager As DataPager = CType(sender.BindingContainer, DataPager)


Dim i As Integer


If lvPager IsNot Nothing Then

Dim Pages As Integer = System.Math.Ceiling(lvPager.TotalRowCount / lvPager.PageSize)

Dim CurrentPage As Integer = System.Math.Ceiling((lvPager.StartRowIndex + 1) / lvPager.PageSize)


Dim ddlPages As DropDownList = lvPager.Controls(0).FindControl("ddlPages")


If ddlPages IsNot Nothing Then

For i = 1 To Pages

Dim lstItem As New ListItem(i)

If i = CurrentPage Then

lstItem.Selected = True

End If

ddlPages.Items.Add(lstItem)

Next

End If


End If

End Sub

Protected Sub lvPager_OnPagerCommand(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DataPagerCommandEventArgs)
If e.CommandName = "Page" Then

Select Case e.CommandArgument

Case "Next"

Dim newIndex As Integer = e.Item.Pager.StartRowIndex + e.Item.Pager.PageSize

If newIndex <= e.TotalRowCount Then

e.NewStartRowIndex = newIndex

e.NewMaximumRows = e.Item.Pager.MaximumRows

End If

Case "Prev"

e.NewStartRowIndex = e.Item.Pager.StartRowIndex - e.Item.Pager.PageSize

e.NewMaximumRows = e.Item.Pager.MaximumRows

Case "First"

e.NewStartRowIndex = 0

e.NewMaximumRows = e.Item.Pager.MaximumRows

Case "Last"

e.NewStartRowIndex = System.Math.Floor(e.Item.Pager.TotalRowCount / e.Item.Pager.PageSize) * e.Item.Pager.PageSize

e.NewMaximumRows = e.Item.Pager.MaximumRows

End Select


End If

End Sub

Protected Sub ListView_DataBound(ByVal sender As Object, ByVal e As System.EventArgs)
Dim lvPager As DataPager = CType(sender, ListView).FindControl("lvPager")

Dim chkPaging As CheckBox = CType(sender, ListView).FindControl("AllowPaging")

If chkPaging.Checked Then

lvPager.PageSize = 10

lvPager.SetPageProperties(lvPager.StartRowIndex, 10, False)

Else

lvPager.PageSize = lvPager.TotalRowCount

lvPager.SetPageProperties(0, lvPager.TotalRowCount, False)

End If

End Sub
And don't forget the following snippet of CSS:
.lvPagerow { background-color: #284775; color: white; text-align: center; }
Now add your own salt and pepper to taste. DONE!

You're welcome.

No comments: