AKA Marketing.com Logo            VISIT THE BLOG            

Blogged thoughts, is our web blog. Expect views, opinion, rants and tirades about everything and anything 

« Home / Forums »        

Subscribe to our SEO / IT related blog by entering your email address below

Blogged thoughts

| by the www.akamarketing.com team



Repeater paging with an SqlDataSource in ASP.Net

The ASP.Net repeater control has over the last while become one of my favourite controls due to the fact it can be highly customised because it’s a templated control. Two shortcomings with the current implementation of the repeater control however are its lack of paging and sorting capabiltites. Of these I believe paging is perhaps the more desirable feature and thus I will now provide an outline of how to implement paging with a repeater using an SqlDataSource. I’ve chosen to work with an SqlDataSource as this I imagine is the most common underlying data source used with repeaters. 

PagedDataSource class
The most popular way ASP.Net developers enable repeaters to page through large amounts of results is with the help of the PagedDataSource class. This is a class which

Encapsulates the paging-related properties of a data-bound control (such as DataGrid, GridView, DetailsView, and FormView) that allow it to perform paging and is used by control developers when providing paging support to a custom data-bound control.

Since this class can be used to provide paging support to custom data-bound controls it can of course be used by built in data-bound controls such Repeaters and DataLists to provide the same support. If you look on the MSDN page which I have linked to above you’ll notice however that the class implements the ICollection interface. This means that any underlying source you want to feed into the PagedDataSource class (which in turns feeds into the repeater itself) must also implement ICollection. The SqlDataSource class does not implement this interface and thus we must put the data into some class that does implement ICollection, in this case we are using a DataView. OK lets look the c# code behind.

  1. public partial class _Default : System.Web.UI.Page
  2. {
  3.     PlaceHolder innerPlaceHolder = new PlaceHolder();
  4.     protected void Page_Load(object sender, EventArgs e)
  5.     {
  6.         Session[“pageNumber”] = 1;
  7.         Page_with_Repeater();
  8.         int totalResults = (int)Session[“totalResults”];
  9.  
  10.         //five represents the page size - could you session/viewstate
  11.         //to avoid hardcoding but for this sample it’s fine.
  12.         float numOflinks = ((float)totalResults / 5);
  13.        
  14.         //determine how many links to create/display
  15.         if (numOflinks % 1 == 0) numOflinks = (int)numOflinks;
  16.         else if(numOflinks % 1 != 0) numOflinks = (int)numOflinks + 1;
  17.        
  18.         for (int i = 1; i < numOflinks+1; i++)
  19.         {
  20.             LinkButton PagingLink = new LinkButton();
  21.             PagingLink.ID = “pagelink” + i.ToString();
  22.             PagingLink.Text = i.ToString();
  23.             PagingLink.Visible = true;
  24.             PagingLink.CommandArgument = i.ToString(); //used to detect result page required
  25.             PagingLink.Command += new CommandEventHandler(PagingLink_Command);
  26.             innerPlaceHolder.Controls.Add(PagingLink);
  27.         }
  28.     }
  29.  
  30.     public void Page_with_Repeater()
  31.     {
  32.         //SqlDataSource does not implement ICollection and
  33.         //thus will not work with PageDataSource we therefore use
  34.         //a DataView instead which implements all required Interfaces
  35.         DataSourceSelectArguments arg = new DataSourceSelectArguments();
  36.         DataView dv = (DataView)SqlDataSource1.Select(arg);
  37.  
  38.         //Instantiate an instance of PagedDataSource
  39.         //and sets its main properties
  40.         PagedDataSource PagedResults = new PagedDataSource();
  41.         PagedResults.DataSource = dv;
  42.         PagedResults.AllowPaging = true;
  43.         PagedResults.PageSize = 5; //CHANGE THIS ABOVE TOO
  44.  
  45.         int pageIndex;
  46.         Int32.TryParse(Session[“pageNumber”].ToString(), out pageIndex);
  47.         PagedResults.CurrentPageIndex = pageIndex-1; //because this is indexed based
  48.  
  49.         //after the PagedDataSource class is in place we can then
  50.         //feed this into the repeater itself
  51.         repeater1.DataSource = PagedResults;
  52.         repeater1.DataBind(); //repeater does not bind natively
  53.  
  54.         //configure paging number - Google Style
  55.         //to do this we dynamically create X amount of links based on the total
  56.         //results and the PageSize - we can’t create these buttons here as
  57.         //events will only run if added in design time or page_init/page_load
  58.         Control OuterPanel = FindControlRecursive(repeater1, “placeLinks”);
  59.         OuterPanel.Controls.Add(innerPlaceHolder);
  60.     }
  61.  
  62.     protected void SqlDataSource1_Selected(object sender, SqlDataSourceStatusEventArgs e)
  63.     {
  64.         //variable used to create X amount of buttons
  65.         Session[“totalResults”] = e.AffectedRows;
  66.     }
  67.  
  68.     protected void PagingLink_Command(object sender, CommandEventArgs c)
  69.     {
  70.         Session[“pageNumber”] = c.CommandArgument.ToString();
  71.         Page_with_Repeater();
  72.     }
  73.  
  74.     private Control FindControlRecursive(Control root, string id) { } //removed for clarity
  75.  
  76. }

All the important paging related code is encapsulated in the Page_with_Repeater() function, it’s all commented so I won’t repeat myself here. As far as what the code does, well it displays 5 rows of data at a time from the underlying datasource (in this case SqlDataSource1) in a repeater. LinkButtons are dynamically created and then added to the repeater to display page numbers as links to allow the user to select a specific result page. Often interfaces allow the user to select a specific page (as in this example) and to use previous and next buttons for working his or her way through data, on that note a good example of using buttons for repeater paging is given on the 4guysfromrolla.com website. 

The corresponding .aspx markup for the c# code is very simple and contains a repeater (named ‘repeater1′) with an embedded panel (named ‘placeLinks’) and an SqlDataSource (named ‘SqlDataSource1′) which specifies an event hander for the ’selected’ event in order for us to create the correct amount of paging links.

Incidentally you may notice in the C# code above that I have used a custom function called FindControlRecursive to enable me to add the dynamically created placeholder (which contains all the page number linkbuttons) to the statically created panel within the repeater. This is a handy function I came across recently and which I often use in conjunction with repeater controls (and many other controls too). It accepts a root control and an id of the target control to look for. It works in a similar way to the standard FindControl method except it searches all controls (including child controls) in a control tree hierachy whereas FindControl will only search the specific control you pass it without examining any child controls.

That’s it - paging with a repeater using an SqlDataSource is implemented. As you can see it is not too difficult. If you have any questions please feel free to ask.  

16 Comments on “Repeater paging with an SqlDataSource in ASP.Net”
1| Chris O said,

Hi, great article, I have been looking for something like this for the past couple of days. I am new to .net so please forgive my ignorance!
when i run my page I get the following error : ‘testPaging.FindControlRecursive(System.Web.UI.Control, string)’: not all code paths return a value.

On this line of code: private Control FindControlRecursive(Control root, string id) { } //removed for clarity

I am at a loss as what I am doing wrong or where to go from here. If i remove the line that is causing this error and also the following lines:
Control OuterPanel = FindControlRecursive(repeater1, “placeLinks”);
OuterPanel.Controls.Add(innerPlaceHolder);

I can control how many results are displayed on my page by setting the value of PagedResults.PageSize
If anyone can point me in the right direction as to how to get the navigation for the pages working I would b very grateful!

2| David Callan said,

Hi Chris, perhaps this is not the problem but have you gotten the rest of the FindControlRecusive function from the link I point to in the 2nd last paragraph? I removed the code inside the function to make it clearer!

3| Chris O said,

Hi David, thanks for the help! I now have paging on my page! I was missing the code for that function, my head has been fried this past few days trying figuring this stuff out.
I am unsure what you mean by specifying an event handler for the ’selected’ event on the SqlDataSource. Could you please explain this or provide a simple example? Also, what is the best way to get the total number of results into the session variable “totalResults”?
Thank you.

4| Chris O said,

I figured this out, me being silly I guess and not fully looking at the code…again! I just added the following to my asp:sqlDataSource tag on my aspx page:

OnSelected=”SqlDataSource1_Selected”

Thanks again for the article!

5| Chris O said,

I am now trying to give the user a choice as to how many results they want per page by means of a drop down list. I have created a method that chages the page size based on what is selected from the drop down by creating a variable called resultsPerPage and usingit as follows:
float numOflinks = ((float)totalResults / resultsPerPage );
PagedResults.PageSize = resultsPerPage;

however my page numbering is way off and when I click on an item in the repeater it looses the previous selection in the dropdown and restores it to the 1’st value in the list, and restoring the number of results per page to the 1st value of the drop down. I hop I make sense!
any suggestions!?
thanks

6| Ash said,

Hey, I was wondering if maybe someone could help me convert the above code to VB?

I’ve done most of it, but as a n00b to ASP.NET and VB I think I’ve made some errors, my code I’m struggling with is:

PagingLink.CommandArgument = i.ToString() ‘used to detect result page required
PagingLink.Command &= New CommandEventHandler(PagingLink_Command)

It’s saying “‘Public Event Command(sender As Object, e As System.Web.UI.WebControls.CommandEventArgs)’ is an event, and cannot be called directly. Use a ‘RaiseEvent’ statement to raise an event.”

Other than that the code seems to be working (the page loads if i comment that line out showing only 5 results).

Any help would be appreciated.

Thanks

7| David Callan said,

Hi Ash, sorry for the delay in the reply. The site has been down over most of the weekend. Unfortunately I’m not a VB man myself but I would recommend getting yourself set up on forums.asp.net and post your problem there. There’s a tonne of both C# and VB developers which regularly help people out.

8| Steve said,

When I enter this and run it, I get this error:

Both DataSource and DataSourceID are defined on ‘repeater1′. Remove one definition.

9| Piotr said,

Just to say thank you! Top job

10| Ryan Pajarillaga said,

Cool.. Thanks to your article, I saved time in doing my work..

11| J said,

Hi,

the link for the function FindControlRecursive don’t work anymore. Can you post it agai, please?

12| j2flk said,

Hi,

I tried to follow this example…it all works well except when I create my aspx page i end up getting the panel of numbers after the first item in the repeater…i need it to be after the last item on the page…any idea what i’m doing wrong?

Privacy
Testing Only

<asp:LinkButton ID=”lnkCountryname” runat=”server” Text=”>

13| Daniel said,

Excellent article, it was very helpful.
Thank you!

14| ashish said,

When I enter this and run it, I get this error:

Both DataSource and DataSourceID are defined on ‘repeater1′. Remove one definition.

15| ashish said,

can someone plz help on the above error
thnx in advance

16| 10 Top most links to learn Asp.net Repeater control | Webpru said,

[...]   Repeater paging with an SqlDataSource in ASP.Net   http://www.akamarketing.com/blog/66-repeater-paging-with-an-sqldatasource-in-aspnet.html [...]

Leave a Comment
Name:
Email:
Website:
 
HOME | ABOUT US | CONTACT US | SITEMAP | GOOGLE SITE SEARCH | TOP
12 Lorcan Crescent, Santry, Dublin 9, Ireland +353 87 9807629