Introduction

I have seen some examples of making a Repeater to work with a DataPager like it does with the ListView control. But all examples failed when I tried them, and I spent some time to get this to work. Here is my solution.

Using the code

First, create a Custom Web Control with the name DataPagerRepeater. Inherit it from Repeater and include the System.Web.UI.WebControls.IPageableItemContainer namespace (this requires that you add a reference to System.Web.Extensions).

The following code will guide you how to work with databind when not using presistentDataSource.

In default.aspx.cs (the codebehind file) of the download code example.
Replace entire page code with this and you see how it works.

There are also an example when using datasource paging:
Uncomment the parts under
////***DATASOURCE PAGING***
and comment the parts under
//**PAGING IN REPEATER ALWAYS LOAD DATA PersistentDataSource = false;

The following code will guide you to how to work with databind when not using presistentDataSource
In default.aspx.cs (the codebehind file) of the download example.
Replace entire page code with this and you see how it works.

The property PersistentDataSource = true will try to cache your data bll.SpecialAds into the page viewstate (so you don't have to reload the repeater with new data for each page click). You can solve this by adding the attribute "serializable" to the bll.specialAds class OR you can set the PersistentDataSource to False but then you need to reload the data at every page click

I implemented sorting with this - but found the datarepeater was displaying data from one click ago - even though the datasource is correct and the databind is done just after. - I belive it may have something to do with the persistent datasource - but when I turn that off I get a null returned from GetData().

My understanding is that when the FetchingData event is raised, I should re-bind the repeater with the next or previous page of data and set the total records. The problem I'm having is that that the FetchingData event is raised before the new StartRowIndex value is set by the DataPager so essentially, all I can do is rebind the previous page of data.

What I ended up doing is checking for IsPostBack in the SetPageProperties method (because it seems that the DataPager eventually calls it) and doing the same checks you did in OnLoad then calling FetchingData there. Paging now works correctly with the intended page of data but only because FetchData is now called twice, thus doubling my calls to the database.

Is this working for anyone? Is there a way call FetchingData only after the new page index has been set by the DataPager?

I'm having a problem when using DataPagerRepeater inside an Update Panel.
What happens is that on a button I rebind the repeater to a new data source and calls the update panel update().
The bug is that the repeater isn't update with the new data.
I've traced the databind function and what happens is that on the GetData() function I get the old data and it is not being replaced with the DataSource property.

Sorry, but there seems to be another problem now.
When I have a LinkButton inside my updatepanel , everything works ok.
When I have a button, I get the following error:
"
Message: Sys.WebForms.PageRequestManagerServerErrorException: Invalid postback or callback argument. Event validation is enabled using <pages enableEventValidation="true"/> in configuration or <%@ Page EnableEventValidation="true" %> in a page. For security purposes, this feature verifies that arguments to postback or callback events originate from the server control that originally rendered them. If the data is valid and expected, use the ClientScriptManager.RegisterForEventValidation method in order to register the postback or callback data for validation.
"

If I replace the DataPagerRepeater with a regular Repeater, then the everything works correct.

From SQL2005 and up you can do a quick pageing in db with the ROW_NUMBER()/OVER function and a #temp table

--Pageingparams
@PageIndex int,
@PageSize int
--
Select ROW_NUMBER() OVER (ORDER BY col1)AS Row, --Add this the old existing unpaged query and move ORDER BY to the OVER command
col1,
col2,
col3
into #temp --Add this to the old existing unpaged query
from table1
Where col1 = [somevalue]
--This part will be the same for all paged queries
Select *
from #temp
WHERE Row between (@PageIndex +1) and @PageIndex + @PageSize
Select count(*) as TotalRows
FROM #temp
Drop table #temp

I tried to use it in my site.
I have two DataPagerRepeater on my page.
One of them works great but the other one doesn't work.
I get NullReferenceException in DataBind() because base.GetData() returns null.

It is great article and i am using ur code to achieve paging in repeater.
But i found one bug which was causing some problem when pagesize changes.
Please confirm is it right or wrong?
I have change this line
if (item.ItemIndex >= (int)ViewState["_startRowIndex"] && item.ItemIndex <= ((int)ViewState["_startRowIndex"] + (int)ViewState["_maximumRows"]))
to
if (item.ItemIndex >= (int)ViewState["_startRowIndex"] && item.ItemIndex <= ((int)ViewState["_startRowIndex"] + (int)((int)ViewState["_maximumRows"]-1)))

Note extra "- 1" at the end..Else even if i set the pagesize to 2 then it was showing 3 items