Photo of the Day

Just taking a walk around the mountain!
The ALBUMS section is full of stuff! Here's today's pick!

download photo

See more photos

Todd's Blog Return to catagory list

 

ASP.Net Paging Control....Google Style!!!
Article Number: 62 Date Added: 08/03/2009 16:06:51
Total Views: 486 (Not rated) Total Rating: 0

So you need to page your data. Simple enough. Most of the data controls have embedded paging and turing it on is simple.

What isn't simple, is making it look half way decent! So I thought "...I wonder if I could build a generic paging control to mimic the Google-esk style!" Well...here goes...

I'm going to give you the code first, then explain what's happening. Remember to rate and comment if your just here for the code!

There are three files. A UserControl and it's code behine and a display page.

User Control

*****START*****

<%@ Control Language="VB" AutoEventWireup="false" CodeFile="PagerControl.ascx.vb" Inherits="PagerControl" %>

<style type="text/css">

.RemoveAll {padding:0;margin:0;border:none;}

</style>

<table>

<tr>

<td align="right" valign="bottom" class="RemoveAll">

<asp:HyperLink ID="hypPrevPage" runat="server" CssClass="RemoveAll">

<asp:Image ID="imgLeftImage" runat="server" CssClass="RemoveAll" />

</asp:HyperLink>

</td>

<asp:PlaceHolder ID="plcRepeatedImages" runat="server" />

<td align="left" valign="bottom" class="RemoveAll">

<asp:HyperLink ID="hypNextPage" runat="server" CssClass="RemoveAll" >

<asp:Image ID="imgRightImage" runat="server" CssClass="RemoveAll" />

</asp:HyperLink>

</td>

</tr>

<tr>

<td align="center" valign="top" class="RemoveAll">

<asp:HyperLink ID="hypPrevPage2" runat="server" Text="Prev" CssClass="RemoveAll" />

</td>

<asp:PlaceHolder ID="plcPageNumbers" runat="server" />

<td align="center" valign="top" class="RemoveAll">

<asp:HyperLink ID="hypNextPage2" runat="server" Text="Next" CssClass="RemoveAll" />

</td>

</tr>

</table>

*****STOP*****

User Control Code Behind

*****START*****

Imports System.Web.UI.WebControls

Imports System.Data

Imports System.Data.Sql

Imports System.Data.SqlClient

Imports MyCustomDAlayer.DataAccessLayer

Partial Class PagerControl

Inherits System.Web.UI.UserControl

Private _PagesToDisplay As Integer = 0

Private _ConnectionString As String = String.Empty

Private _SelectCommand As String = String.Empty

Private _SelectCommandType As System.Data.CommandType = CommandType.StoredProcedure

Private _ControlToPage As String = String.Empty

Private _ItemsPerPage As Integer = 10

Private _LeftImage As String = String.Empty

Private _RepeatImage As String = String.Empty

Private _RightImage As String = String.Empty

#Region "Control Properties"

'the number of images to display in the control as page links

Public Property PagesToDisplay() As Integer

Get

Return _PagesToDisplay

End Get

Set(ByVal value As Integer)

_PagesToDisplay = value

End Set

End Property

'the connection string to use to connect to the DB

Public Property ConnectionString() As String

Get

Return _ConnectionString

End Get

Set(ByVal value As String)

_ConnectionString = value

End Set

End Property

'The SQL SELECT command to use, either SQL string or Stored Procedure name

Public Property SelectCommand() As String

Get

Return _SelectCommand

End Get

Set(ByVal value As String)

_SelectCommand = value

End Set

End Property

'The SQL Command type

Public Property SelectCommandType() As System.Data.CommandType

Get

Return _SelectCommandType

End Get

Set(ByVal value As System.Data.CommandType)

_SelectCommandType = value

End Set

End Property

'the name of the control to paginate

Public Property ControlToPage() As String

Get

Return _ControlToPage

End Get

Set(ByVal value As String)

_ControlToPage = value

End Set

End Property

'Gets and sets the 1-based index of the page

Public Property CurrentPageIndex() As Integer

Get

Dim o As Object = Me.ViewState("_CurrentPage")

If IsDBNull(o) Or o Is Nothing Then

Return 1

Else

Return CInt(o)

End If

End Get

Set(ByVal value As Integer)

Me.ViewState("_CurrentPage") = value

End Set

End Property

'Gets and sets the number of records to display per page. Default is 10

Public Property ItemsPerPage() As Integer

Get

Return _ItemsPerPage

End Get

Set(ByVal value As Integer)

_ItemsPerPage = value

End Set

End Property

'the full path of the image to display as the left side image

Public Property LeftImage() As String

Get

Return _LeftImage

End Get

Set(ByVal value As String)

_LeftImage = value

End Set

End Property

'the full path of the image to display, repeated depaending on page number

Public Property RepeatImage() As String

Get

Return _RepeatImage

End Get

Set(ByVal value As String)

_RepeatImage = value

End Set

End Property

'the full path of the image to display as the right side image

Public Property RightImage() As String

Get

Return _RightImage

End Get

Set(ByVal value As String)

_RightImage = value

End Set

End Property

#End Region

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

'ensure there is a control to paginate

If IsDBNull(_ControlToPage) Then Exit Sub

'ensure there is a connection string and command

If _ConnectionString = "" Or _SelectCommand = "" Then Exit Sub

'handle link click

If Not Request.QueryString("Pg") Is Nothing Then

CurrentPageIndex = Integer.Parse(Request.QueryString("Pg"))

End If

Dim MyPagedData As New PagedDataSource

Dim MyDS As New DataSet

MyDS = SqlHelper.ExecuteDataset(_ConnectionString, _SelectCommandType, _SelectCommand)

MyPagedData.DataSource = MyDS.Tables(0).DefaultView

MyPagedData.AllowPaging = True

MyPagedData.PageSize = _ItemsPerPage

MyPagedData.CurrentPageIndex = CurrentPageIndex - 1

Dim PageCount As Integer = 1

Dim StartPageNumber As Integer = 1

Dim StopPageNumber As Integer = _PagesToDisplay

If _PagesToDisplay > MyPagedData.PageCount Then

_PagesToDisplay = MyPagedData.PageCount

StopPageNumber = MyPagedData.PageCount

Else

Dim tmp As Integer = CurrentPageIndex - 1

If tmp >= _PagesToDisplay Then

Dim intH As Integer = CurrentPageIndex \ _PagesToDisplay

StartPageNumber = (intH * _PagesToDisplay) + 1

StopPageNumber = (intH * _PagesToDisplay) + _PagesToDisplay

If StopPageNumber > MyPagedData.PageCount Then

StopPageNumber = MyPagedData.PageCount

End If

End If

End If

 

imgLeftImage.ImageUrl = _LeftImage

imgRightImage.ImageUrl = _RightImage

If CurrentPageIndex = MyPagedData.PageCount Then

hypNextPage2.Visible = False

Else

hypNextPage.NavigateUrl = Request.CurrentExecutionFilePath & "?Pg=" & (CurrentPageIndex + 1)

hypNextPage2.NavigateUrl = Request.CurrentExecutionFilePath & "?Pg=" & (CurrentPageIndex + 1)

End If

If CurrentPageIndex = 1 Then

hypPrevPage2.Visible = False

Else

hypPrevPage.NavigateUrl = Request.CurrentExecutionFilePath & "?Pg=" & (CurrentPageIndex - 1)

hypPrevPage2.NavigateUrl = Request.CurrentExecutionFilePath & "?Pg=" & (CurrentPageIndex - 1)

End If

For PageCount = StartPageNumber To StopPageNumber

Dim New_Table_Cell1 As New HtmlTableCell

Dim New_Table_Cell2 As New HtmlTableCell

Dim PageHyperlink As New HtmlAnchor

Dim NumericHyperlink As New HtmlAnchor

Dim NumericLabel As New Label

Dim RepeaterImage As New HtmlImage

New_Table_Cell1.Attributes.Add("valign", "top")

New_Table_Cell1.Attributes.Add("class", "RemoveAll")

RepeaterImage.Src = Page.ResolveUrl(_RepeatImage)

RepeaterImage.Alt = "Page " & PageCount

RepeaterImage.Attributes.Add("class", "RemoveAll")

If PageCount = CurrentPageIndex Then

New_Table_Cell1.Controls.Add(RepeaterImage)

NumericLabel.Text = PageCount

New_Table_Cell2.Attributes.Add("align", "center")

New_Table_Cell2.Attributes.Add("valign", "bottom")

New_Table_Cell2.Attributes.Add("class", "RemoveAll")

New_Table_Cell2.Controls.Add(NumericLabel)

Else

PageHyperlink.Controls.Add(RepeaterImage)

PageHyperlink.Target = "_self"

PageHyperlink.HRef = Request.CurrentExecutionFilePath & "?Pg=" & PageCount

PageHyperlink.Attributes.Add("class", "RemoveAll")

New_Table_Cell1.Controls.Add(PageHyperlink)

NumericHyperlink.Target = "_self"

NumericHyperlink.HRef = Request.CurrentExecutionFilePath & "?Pg=" & PageCount

NumericHyperlink.InnerText = PageCount

NumericHyperlink.Style.Add("text-decoration", "none")

New_Table_Cell2.Attributes.Add("align", "center")

New_Table_Cell2.Attributes.Add("valign", "bottom")

New_Table_Cell2.Attributes.Add("class", "RemoveAll")

New_Table_Cell2.Controls.Add(NumericHyperlink)

End If

plcPageNumbers.Controls.Add(New_Table_Cell2)

plcRepeatedImages.Controls.Add(New_Table_Cell1)

Dim MyGrid As New GridView

MyGrid = Me.Parent.FindControl(_ControlToPage)

MyGrid.DataSource = MyPagedData

MyGrid.DataBind()

Next

End Sub

End Class

*****STOP*****

Display Pages (Default.aspx there is NO code behind!)

*****START*****

<%@ Page Language="VB"  %>

<%@ Register src="~/PagerControl.ascx" tagname="PagerControl" tagprefix="uc1" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >

<head id="Head1" runat="server">

<title>Untitled Page</title>

</head>

<body>

<form id="form1" runat="server">

<div>

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="True" />

<center>

<uc1:PagerControl ID="Paging_Control1" runat="server"

ConnectionString="<%$ ConnectionStrings:MyConnectionString %>"

ControlToPage="GridView1"

ItemsPerPage="10"

PagesToDisplay="10"

LeftImage="~/Images/LeftImage.gif"

RepeatImage="~/Images/RepeatImage.gif"

RightImage="~/Images/RightImage.gif"

SelectCommand="My_Stored_Procedure_To_Get_Data"

SelectCommandType="StoredProcedure"

/>

</center>

</div>

</form>

</body>

</html>

*****STOP*****

Right....here goes....

In a nutshell, the paging control is actually a "data collector". It gets your data, pages it, sets various properties then passes the paged data to a "display control". In this case Gridview1.

The usercontrol (Paging_Control1) exposes several properties that must be set. I think most of them are self-explanitory, but I'll go through them anyway.

  1. Connectionstring - Your connection string to the database
  2. ControlToPage - The control that will receive the paged data. In the code above, this is GridView1
  3. ItemsPerPage - How many records (items) you want the control to display
  4. PagesToDisplay - This sets the number of repeated "o's" for the control. However, in the code behind we will check that that number to be displayed does no exceed the number available
  5. LeftImage - the full path to the image you want to use on the left of the control. On Google pages, this is the "Go" letters
  6. RepeatImage - the repeated image for each page of data. On Google pages, this is the letter "o"
  7. RightImage - the full path to the image you want to use on the right of the control. On Google pages, this is the "gle >" letters
  8. SelectCommand - either the full SQL text (IE: SELECT * FROM Table1) or the stored procedure name
  9. SelectCommandType - sets what type of command the above is,

The only "dynamic" variable we need to get is the current page index/number. This is stored in viewstate and passed to the control through the QueryString object as well.

When the control "Page_Load" event fires, the select command, connection string and control to page variable are checked. Then the "Page number" variable is checked. A "PagedDataSource" object is filled with a "DataSet" and the paging properties are applied.

The it cycles through and builds the "o's" and number's (below the o's) as HTML controls, loading them into a "PlaceHolder" control when finished.

I could have built this to display nothing if no data was found, but since I'm using it where I know data is present, I didn't bother! ;)

At any rate, it works rather well. This is a base control, loads of room for improvement. I based the idea off of  Dino Esposito's article on MSDN (dated October 2003) where he walks you through building a very boring SQL pager control in C#. The article is very good, I recommend you check it out (http://msdn.microsoft.com/en-us/library/ms972960(printer).aspx). Mine is better! And in VB!!!

Remember to comment and rate!

Have fun!!

 

Rate This Article:



User:
 
Comment:

 

Comments are limited to 250 characters (250 characters remaining)