
Introduction
Paging is an important thing that every web developer should know about. In ASP.NET only DataGrid and GridView has built-in support for paging. In ASP.NET 3.5 Microsoft has provided the first separated pager control for ASP.NET, called DataPager. But unfortunately it just supports paging for controls that they've implemented the IPageableItemContainer interface like ListView. So we still need a simple yet efficient control to do paging over almost any kind of item containers.
Note 1: Although provided source and sample projects are categorized by the ASP.NET version, the Pager control's source is the same inside both ASP.NET 2.0 and ASP.NET 3.5 projects, but the ASP.NET 3.5 project has a sample to show how to utilize LINQ as Pager control's data provider.
Note 2: ASPnetPagerV2.8 doesn't support ASP.NET 1.1 for now.
What a Paging System Needs and What it is Supposed to Provide
Essential things we should provide to our paging system:
- How many items I want to display per page, or "PageSize"
- Which page I am in, or "CurrentIndex"
- How many items(records) I have, or "ItemCount"
Things the paging system is supposed to provide:
- Quasi hyperlinks to easily navigate through pages(see Figure 1)
- Items(results) which I want to show on the current page (like a DataSet or DataTable that is bindable)
What Parts does it Consist Of?
This paging system consists of the following parts and I will try to explain them:
The first part:

A data access engine which gets required parameters from the Pager control and query database or other data source. Again, if you are using ASP.NET 3.5 maybe you want to write this part with LINQ otherwise this part is a Stored Procedure.
Second Part:

The Pager control which generates the hyperlinks for us in a user friendly way. These hyperlinks will be used by user to navigate through the pages.
The last but not the least:

And finally, a web page which hosts the Pager control and show paged results.
Deploying and customizing Pager control
Step by step explanation of Pager control's deployment
1. Write your Own Business Specific Stored Procedure or LINQ Query
1.1 Paging on SQL Server 2000
Let me start with Stored Procedure. It comes with the demo project that you may have downloaded. Take a look at the screenshot below:

(You may want to change the Procedure name, but don't forget to change the procedure name in the host page too)
As you know, a stored procedure is a business specific object, and its parameter names are strongly dependent on the names of your business objects. So, you should customize some of its variables. To make the world easy for myself and of course for you, I colorized the sections we have a special focus on them.
To modify the stored procedure to fit into your business, do the following. We will start from the bottom to top:
- The blue section (except the
RowNumber statement) means the output columns that you want to show on the web page. So first of all, write your own table's columns here right after the RowNumber statement. For example, assume that you want to show the "Title", "Price", and "PubDate" columns of the "Pubs" database. The blue section will change to:
"SELECT RowNumber, Title, Price, PubDate"
- The green section means your "Select Logic". According to our example, if you have no
"WHERE" statement in your query, the green section will change to:
"SELECT Title, Price, PubDate FROM Titles"
- and if you have to use the
"WHERE" statement for example, it will change to this:
"SELECT Title, Price, PubDate FROM Titles WHERE Price > 11"
- You may use other T-SQL statements to sort the rows. As you can see, in the green section, I used an
"ORDER BY" statement to sort my results. It is optional and up to you. In our example, we may want to sort our results by Title, so we modify it to:
"SELECT Title, Price, PubDate FROM Titles WHERE Price > 11 ORDER BY Title"
- OK, the pink section is part of a procedure that creates a temporary table, add your blue section's (except
RowNumber) columns to it. In our example, the pink part would change to:
"Title varchar(80), Price money, PubDate datetime"
- And the last part is the yellow section. This section really relies on part 2 (the green guy!). In our example if we don't use
"WHERE" in the green part, the yellow section will become:
"SELECT COUNT(*) FROM Pubs"
- And if we use
"WHERE" in the green part, it will become:
"SELECT COUNT(*) FROM Pubs WHERE Price > 11"
1.2 Paging on SQL Server 2005
SQL Server 2005 supports paging internally via the ROW_NUMBER() function. Take a look at the figure below:

Create the stored procedure in your database, and carry on.
2. Declare and Customize Pager Control
Let's see how we can use it and how it can play its role in our paging system. You can customize the Pager control via its properties. I've divided the properties into two main categories:
Globalization
As the name shows, the language of the captions in the Pager control can be changed with these properties. Let's take a look at the screenshot below:

Default language is (en-us) but you can easily change this property to change the Pager control's caption language, even to Unicode languages like Persian or Arabic. Also, there is a property, named RTL, which changes the direction of the Pager control from LeftToRight(default) to RightToLeft.
Behavioural
You can change the behaviour of your Pager control here. Actually, the main customization happens here.

Basic Behavioural Properties
PageSize
Gets or sets a value that indicates how many items should be displayed per page
Default: 15
CompactModePageCount
Gets or sets a value that indicates how many page numbers should be rendered in compact mode
Example: imagine CompactModePageCount=10, so while the CurrentIndex is lower than 10, the page number count(Pager hyperlinks) would be 10, otherwise the count of the page numbers would be equal to NormalModePageCount's value
Default: 10
NormalModePageCount
Gets or sets a value that indicates how many page numbers should be rendered in normal(not compacted) mode
Default: 15
GenerateToolTips
Gets or sets a value that indicates whether generate tooltips
Default: True
GenerateFirstLastSection
Gets or sets a value that indicates whether generate the First and Last sections
Default: False
GeneratePagerInfoSection
Gets or sets a value that indicates whether generate the left most table cell that shows CurrentIndex and total page count information
Default: True
GenerateGoToSection
Gets or sets a value that indicates whether generate the GoTo section
Default: False
SmartShortcuts Properties
SmartShortcuts were introduced in V2.0 and they improved efficiency, especially in large scale data scenarios. They are really cool and are shown in figure-1 in gray backgrounded cells.
GenerateSmartShortCuts
Gets or sets a value that indicates whether generate Smart Shortcut section
Default: True
MaxSmartShortCutCount
Gets or sets a value that indicates how many smart shortcut can be generated at most
Default: 6
SmartShortCutThreshold
Gets or sets a value that if total page counts are greater than this value, SmartShortcuts will be generated
Default: 30
SmartShortCutRatio
Gets or sets a value that SmartShortcut engine will use internally to handle calculation. 3 is recommended.
Default: 3
Hidden Hyperlinks Properties
After releasing the PagerControl V2.0 some developers contacted me and requested the previous version. I asked them why they wanted the previous version and I found out they were interested in the first version because it was based on QueryString parameters and they didn't want to hide their hyperlinks from search engine bots. So to have the best of both worlds I came up with an idea to generate hyperlinks automatically in a hidden container. But a serious question was raised before developing this feature could begin: "Is hidden text visible to search engine bots?" and luckily the answer is "YES".

The figure above shows a visibility test with Lynx
To see the hyperlinks in action switch this property on and view the page source
3. The Host Web Page
Let's continue and complete our paging system. As you can see in the demo project, we have a web page which hosts our controls (Repeater for repeating the results and the Pager control). Let's see what happens if a user requests that page:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
BindRepeater();
}
}
If a user clicks on a hyperlink to naviaget to a page, the OnCommand event gets fired and the event handler gets executed:
public void pager_Command(object sender, CommandEventArgs e)
{
int currnetPageIndx = Convert.ToInt32(e.CommandArgument);
pager1.CurrentIndex = currnetPageIndx;
BindRepeater();
}
To get the paged results BindRepeater() method should be called:
private void BindRepeater()
{
string strConn = ConfigurationManager.ConnectionStrings[
"northwindConnectionString"].ConnectionString;
SqlConnection cn = new SqlConnection(strConn);
SqlCommand Cmd = new SqlCommand("dbo.GetPagedProducts_sql2k5", cn);
Cmd.CommandType = CommandType.StoredProcedure;
SqlDataReader dr;
Cmd.Parameters.Add("@PageSize", SqlDbType.Int, 4).Value = pager1.PageSize;
Cmd.Parameters.Add("@CurrentPage", SqlDbType.Int, 4).Value = pager1.CurrentIndex;
Cmd.Parameters.Add("@ItemCount", SqlDbType.Int).Direction = ParameterDirection.Output;
cn.Open();
dr = Cmd.ExecuteReader();
rptProducts.DataSource = dr;
rptProducts.DataBind();
dr.Close();
cn.Close();
Int32 _totalRecords = Convert.ToInt32(Cmd.Parameters["@ItemCount"].Value);
pager1.ItemCount = _totalRecords;
}
Colorize and Customizing the Pager Control's Style
Hope everything is going well. If you are done with deployment, let's go to customize the Pager control's style. I've created two CSS stylesheets that can colorize the Pager control in two different ways.
LightStyle.css: Provides the below style for your Pager control (recommended for light background web pages).

DarkStyle.css: Provides the below style for your Pager control (recommended for dark background web pages).

(To customize the control's style in your preferred way, you should manipulate the stylesheet classes in the "Styles" folder).
Acknowledgements
Launching V2.8 coincided with the 3rd anniversary of the ASP.NET Pager Control. I just wanted to say thanks to every single feedback you gave. I think without your help this control couldn't come this far. If you are using this control and you are happy with it, thats great. And I am happy to hear from you if you have a special feature in mind; features are important to me because they can help this control grow and become more useful.
History
- Sep, 2008: V2.8
New features: Hidden Hyperlinks, GoTo section, ability to hide Pager information section, ViewState independent
Fixed Issue: Pager control loses state after page postback bug has been resolved
- Nov, 2006: V2.0
New features: Postback approach instead of hyperlinks, SmartShortcuts
- Aug, 2005: V1.0
First release
| You must Sign In to use this message board. |
|
|
 |
|
 |
I added the pager control to my web application which is build on .NET 2.0 but using Visual Studio 2008. The problem is that when I am trying to write some code (in code behind) there is no instance of pager control. I tryied .NET 2.0 version and .NET 3.5 version of pager control but the same problem happened. Does anyone have any idea?
Thanks
Peter Manesis
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
 |
|
 |
The ItemCount property is described as the "total number of rows". As such, it can only be a positive whole number or 0. There is no point in using a floating-point type for this. It should be an integer type.
|
| Sign In·View Thread·PermaLink | 2.00/5 |
|
|
|
 |
|
 |
A quick note for anybody else who's scratching their head. The following will display an incorrect number of pages:-
protected void Page_Load(object sender, EventArgs e) { pagTest.ItemCount = 53; pagTest.PageSize = 10; } But the following will display the correct number of pages:-
protected void Page_Load(object sender, EventArgs e) { pagTest.PageSize = 10; pagTest.ItemCount = 53; }
--- I'm thinking of a song or two, a boy a girl and a rendezvous.
|
| Sign In·View Thread·PermaLink | 5.00/5 |
|
|
|
 |
|
|
 |
|
 |
Hi,
I need to get the hidden hyperlinks to update the querystring value when I click on the pages.
for example, I have the control hidden hyperlinks like this from view source:
page 1
Now, when I click on the page1, I want to update the url of the page to have the href value.
The reason for this is that, I want to avoid multiple postback. Currently, when we click on the page links, it fires page load event, then oncommand event gets fired. Then in the oncommand, I have to do response.redirect to update the querystring value for the page index. (fyi: i have a pageindex query string value that i want to keep track of).
Please shed some light
Thanks Needy
|
| Sign In·View Thread·PermaLink | 2.00/5 |
|
|
|
 |
|
 |
Hi Bidel,
Thanks for this control - very nice. I'm having a little problem, though.
1. Go to: http://tfsfrp.tamu.edu/fdd/directory/ 2. At the bottom, select a page in the pager control (like 5) 3. Then go back up and choose a county and press Submit
The results are correct, but the page count in the pager control is off. Could you help me fix this?
Thank you. Brian
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Hi,
Please see my reply to the thread just below "Incorrect initial Page display"
And make the changes.
Let me know it helps.
Rajaraman
|
| Sign In·View Thread·PermaLink | 2.00/5 |
|
|
|
 |
|
 |
Dear Bidel, How can I move to the last page programmatically? I have looked up its properties and method, but did not find anything. Please enlighten me. Thanks.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Did you try to turn on the property with value "True" by default it is false, it is mentioned in the article text. Lot of properties configurable, please take a re-look.
Property : "GenerateFirstLastSection"
Gets or sets a value that indicates whether generate the First and Last section
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
My page control display as "page1 of 0" without any hyperlink for page number. It will display correctly only after I click on ">" hyperlink on the control. I did assign ItemCount to say, 81 during Page_Load event. Code snippet is as follows: Anybody got any ideas? Thanks in advance.
Protected Sub pager_Command(ByVal sender As System.Object, ByVal e As CommandEventArgs) Handles pager1.Command Dim currnetPageIndx As Int32 = CType(e.CommandArgument, Int32) pager1.CurrentIndex = currnetPageIndx BindAvailableOffers() End Sub
Private Sub BindAvailableOffers() Dim stepOfferDAL As New StepOfferDAL Dim stepOfferList As List(Of StepOffer) = stepOfferDAL.GetAllAvailableOffers(15, pager1.CurrentIndex) LstAvailable.DataSource = stepOfferList LstAvailable.DataBind() pager1.ItemCount = stepOfferDAL.TotalStepOfferCount End Sub
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Did you reproduce this behaviour in the sample downloaded?
If not, are you using this pager inside any other ascx control ?
Rajaraman
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Yes, it is in an ascx control. I will see if I can reproduce the problem in the sample download. But until then, do you have any idea what is going on? Thanks.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Then, you please try changing these two places?
SaveControlState (method) LoadControlState (method)
include "ItemCount" to be stored and retreived.
Let me know it helps?
Rajaraman
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Rajaraman, thanks. It works now after I made following modification to both methods:
protected override object SaveControlState() { object[] objState = new object[4]; objState[0] = CurrentIndex; objState[1] = PageSize; objState[2] = ItemCount; return objState; } protected override void LoadControlState(object state) { object[] savedState = (object[])state; CurrentIndex = (int)savedState[0]; PageSize = (int)savedState[1]; ItemCount = (double)savedState[2]; }
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Hi,
I have placed two pager control on a single .aspx page. If I click on the second GoTo section, the first controls GoTo section is expanded. It is not expanding the second control's GoTo section as expected.
Here is the aspx code if it make sense.
| <cc:pagerv2_8 id="pagerControl1" runat="server" öncommand="pager_Command" generategotosection="true" width="581px" xmlns:cc="#unknown" /> |
<cc:pagerv2_8 id="pagerControl2" runat="server" öncommand="pager_Command" generategotosection="true" width="581px" xmlns:cc="#unknown" /> |
public void pager_Command(object sender, CommandEventArgs e) { int currnetPageIndx = Convert.ToInt32(e.CommandArgument); pagerControl1.CurrentIndex = currnetPageIndx; pagerControl2.CurrentIndex = currnetPageIndx;
PoppulateRepeater(currnetPageIndx, Convert.ToInt32(Session["pagesize"].ToString()), (SortBy)Session["SortBy"]); }
Looks like it is some kind of javascript issue.
I would appreciate if someone can shed some light.
Mahesh
Thanks Needy
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Change the source code, methods.
1. RenderGoToScript 2. RenderGoTo
Change: 1
For example: change the method name: "function handleGoto" to "function handleGoto_" + this.UniqueID
Similarly change "handleGoToVisibility" and calling places.
Change 2 : Similarly elements: 'div_goto' and 'gotoImg'
Hope this helps.
Thanks, Rajaraman
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
<asp:UpdateProgress ID="UpdateProgress1" runat="server" AssociatedUpdatePanelID="UpdatePanel1"> <ProgressTemplate> <img src="~\images\bigrotation2.gif" alt="" /> </ProgressTemplate> </asp:UpdateProgress>
the above is updateprogress. after including this. upon page number click, it says error. any insights?
following is update panel tags.
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Always"> <ContentTemplate></ContentTemplate> <Triggers> <asp:AsyncPostBackTrigger ControlID="pager1" /> </Triggers> </asp:UpdatePanel>
|
| Sign In·View Thread·PermaLink | 2.00/5 |
|
|
|
 |
|
|
 |
|
|
 |
|
 |
I have sent the source code, Please check your email (might have landed in Junk folder?)
Thank you, Rajaraman
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
 |
It seems that, the control is not working if I include a script tag referencing a js file. To make sure the problem is not on my project, I took the demo project, included a script tag and referenced an empty js file. I ran the project and the pager control did not work. If I click on any of the page numbers the control is not responding. If I took out the script tag everything works fine.
Did I miss something?
|
| Sign In·View Thread·PermaLink | 2.00/5 |
|
|
|
 |
|
 |
Hi,
I have used 2 pager controls on a single page and facing few problems.
1. On changing page index of one pager control the other pager control is loosing its state. 2. Clicking GoTo of the second pager control does not work, instead it enables the Pager DropDown of first Pager control.
Your quick response will be highly appreciated.
Regards Zeeshan Dad Khan
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|