Adding paging to a repeater
While the Gridview control has pagination built in, alot of the time, you may want to add pagination into your repeater control as well. Thankfully, ASP.NET has a PagedDataSource object to help accomplish this task.
* remember you must use a datatable/dataset to use pagination, a datareader cannot be used to accomplish this task
Basically, the PagedDataSource object will act as the middle tier between your data object and the binding to the repeater.
For the HTML, let’s just create the repeater and a label to display the current page
<asp:Repeater ID="repeater1" runat="server" >
<ItemTemplate>
<%# Eval("field") %>
</ItemTemplate>
</asp:Repeater>
<asp:Label id="lblCurrentPage" runat="server" />
For the code behind, make sure that all this code is in a method/sub routine for calling later.
C#
private void BindData()
{
string sql = “SELECT field FROM table";
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["string"].ConnectionString);
conn.Open();
SqlDataAdapter da = new SqlDataAdapter(sql, conn);
DataTable dt = new DataTable();
da.Fill(dt);
// Populate the repeater control with the Datatable
PagedDataSource objPds = new PagedDataSource();
objPds.DataSource = dt.DefaultView;
// Indicate that the data should be paged
objPds.AllowPaging = true;
// Set the pagesize
objPds.PageSize = 5;
int curpage;
if (ViewState["Page"] != null)
{
curpage = Convert.ToInt32(ViewState["Page"]);
}
else
{
ViewState["Page"] = 1;
curpage = 1;
}
// Set the currentindex
objPds.CurrentPageIndex = curpage - 1;
// Display the current page
lblCurrentPage.Text = “Page: " + (curpage).ToString() + " of " + objPds.PageCount.ToString();
// Bind the repeater
repeater1.DataSource = objPds;
repeater1.DataBind();
}
VB.Net
Private Sub BindData()
Dim sql as String = “SELECT field FROM table"
Dim conn As SqlConnection = New SqlConnection(ConfigurationManager.ConnectionStrings("string").ConnectionString)
conn.Open()
Dim da As SqlDataAdapter = New SqlDataAdapter(sql, conn)
Dim dt As DataTable = New DataTable()
da.Fill(dt)
' Populate the repeater control with the datatable
Dim objPds As PagedDataSource = New PagedDataSource()
objPds.DataSource = dt.DefaultView
' Indicate that the data should be paged
objPds.AllowPaging = True
' Set the pagesize
objPds.PageSize = 5
dim curpage as Integer
' we'll use ViewState to track the currentindex
If Not (ViewState("Page") Is Nothing) Then
curpage = Convert.ToInt32(ViewState("Page"))
Else
ViewState("Page") = 1
curpage = 1
End If
' Set the currentindex
objPds.CurrentPageIndex = curpage - 1
' Display the current page
lblCurrentPage.Text = “Page: " & (curpage).ToString() & " of " & objPds.PageCount.ToString()
' Bind the repeater
repeater1.DataSource = objPds
repeater1.DataBind()
End Sub
This should show you your repeater listing off the various fields with 5 records per page. You’ll notice a glaring problem, you can’t move from page to page! To do this, we need to add some paging controls
Add the following HTML below the label you created earlier
<asp:LinkButton id="lnkPrev" runat="server" text=" Previous " OnClick="lnkPrev_Click" />
<asp:LinkButton id="lnkNext" runat="server" text=" Next " OnClick="lnkNext_Click" />
Now we have to add the event handler for these Link buttons which will figure out the new page index, update the viewstate and rebind the repeater.
C#
protected void lnkPrev_Click(object sender, EventArgs e)
{
// Set viewstate variable to the previous page
ViewState["Page"] = Convert.ToInt32(ViewState["Page"]) - 1;
// reload the control
BindData();
}
protected void lnkNext_Click(object sender, EventArgs e)
{
// Set viewstate variable to the next page
ViewState["Page"] = Convert.ToInt32(ViewState["Page"]) + 1;
// reload the control
BindData();
}
VB.NET
Protected Sub lnkPrev_Click(ByVal sender As Object, ByVal e As EventArgs)
' Set viewstate variable to the previous page
ViewState("Page") = Convert.ToInt32(ViewState("Page")) - 1
' Reload control
BindData()
End Sub
Protected Sub lnkNext_Click(ByVal sender As Object, ByVal e As EventArgs)
' Set viewstate variable to the next page
ViewState("Page") = Convert.ToInt32(ViewState("Page")) + 1
' Reload control
BindData()
End Sub
That should do it, let me know if you have any questions!
Leave a Comment
If you would like to make a comment, please fill out the form below.
Very easy to implement. I’ve actually extended it further to provide navigation similar to a GridView such as First/Last options, a list of page number as well as a drop down to adjust the number of results per page.
Hey…..can i know where You declare curpage and CurrentPageIndex?
Thanks for the catch Desmond, I had declared curpage in the C# code, but not in the VB.NET code. I’ve updated the example to show where it’s declared (basially right before it’s used)
As for CurrentPageIndex, it’s a property of the PagedDataSource so no need to declare it.
@David…
How did you create the list of page numbers, and make it change according to the next/previous buttons? I’m trying to accomplish something similar, but I can’t quite make it work…
The first sub does the hard and fast work of creating the page numbers for the repeater. The second enables the linkbuttons to do their job. You’ll need to place a asp:panel on your page in the location where you want the index to appear as in
. The code dynamically adds linkbuttons to this panel. Conceivably you could use images instead of linkbuttons if you have the digits 0-9 as images and then combine them as needed for the buttons.
I also added a ‘Results Per Page’ drop down which simply required objPds.PageSize to be pointed to the drop down list as in
‘ Set the pagesize
objPds.PageSize = NumberOfResultsPerPage.SelectedValue
Setting the Autopostback property to true automatically updates the repeater.
Public Sub CreateRepeaterPageMenu()
Dim i As Integer
Dim StartingPageNumber As Integer
Dim EndingPageNumber As Integer
Dim PageCount As Integer
Dim ParentDivWidth As Integer
Dim NewLinkButton As New LinkButton
RepeaterPagesParent.Controls.Clear
‘Center the list of page numbers within its granparent div by dynamically adjusting the width as needed
‘Adjust if we’ll be adding in an option to show more or show less
‘30 is the max number of Page Numbers to display
‘22 is the width of each Page Nubmer’s div and factors in the 2px from the border around the div
If RepeaterDirectoryPageCount < 26 Then
StartingPageNumber = 1
EndingPageNumber = RepeaterDirectoryPageCount
ParentDivWidth = RepeaterDirectoryPageCount * 22
Else
PageCount = 25
ParentDivWidth = 25 * 22
If curpage = StartingPageNumber And curpage RepeaterDirectoryPageCount Then EndingPageNumber = RepeaterDirectoryPageCount
End If
End If
If StartingPageNumber > 1 Then ParentDivWidth = ParentDivWidth + 22
If RepeaterDirectoryPageCount - EndingPageNumber > 0 Then ParentDivWidth = ParentDivWidth + 22
If StartingPageNumber > 1 Then
NewLinkButton = New LinkButton
With NewLinkButton
.ID = “PageDown”
.Text = “…”
.CssClass = “RepeaterPageSelector”
.CommandName = “SelectPage”
.CommandArgument = StartingPageNumber - 1
AddHandler NewLinkButton.Command, AddressOf SelectPage
End With
RepeaterPagesParent.Controls.Add(NewLinkButton)
End If
If RepeaterDirectoryPageCount > 1 Then
For i = StartingPageNumber To EndingPageNumber
‘For the current page insert a Label and grey it out
If i = curpage Then
Dim NewAspLabel = New Label
With NewAspLabel
.ID = “SelectPage_” & i.ToString
.Text = i.ToString
.CssClass = “RepeaterPageSelectorCurrentPage”
End With
RepeaterPagesParent.Controls.Add(NewAspLabel)
Else
NewLinkButton = New LinkButton
With NewLinkButton
.ID = “SelectPage_” & i.ToString
.Text = i.ToString
.CssClass = “RepeaterPageSelector”
.CommandName = “SelectPage”
.CommandArgument = i
AddHandler NewLinkButton.Command, AddressOf SelectPage
End With
RepeaterPagesParent.Controls.Add(NewLinkButton)
End If
Next
End If
‘Add Leading elipse [...]
If RepeaterDirectoryPageCount - EndingPageNumber > 0 Then
NewLinkButton = New LinkButton
With NewLinkButton
.ID = “PageUp”
.Text = “…”
.CssClass = “RepeaterPageSelector”
.CommandName = “SelectPage”
.CommandArgument = StartingPageNumber + 25
AddHandler NewLinkButton.Command, AddressOf SelectPage
End With
RepeaterPagesParent.Controls.Add(NewLinkButton)
End If
End Sub
Public Sub SelectPage(ByVal sender As LinkButton, ByVal e As System.EventArgs)
‘ Set viewstate variable to the next page
ViewState(”Page”) = sender.CommandArgument
‘ Reload control
BindData()
CreateRepeaterPageMenu()
End Sub
The following code when added to BIND() will dynamically hide/show the first, previous, next, last link buttons based on the number of records returned and the current page. It should be added after the .Databind() method is called.
‘Hide the First/Previous LinkButton or Next/Last LinkButton if we’re at the start or end of the records
LnkFirst.Visible = True
lnkPrev.Visible = True
lnkLast.Visible = True
lnkNext.Visible = True
Select Case curpage
Case 1
LnkFirst.Visible = False
lnkPrev.Visible = False
If RepeaterDirectoryPageCount < 2 Then
lnkLast.Visible = False
lnkNext.Visible = False
End If
Case RepeaterDirectoryPageCount
lnkLast.Visible = False
lnkNext.Visible = False
End Select
Forgot this bit…
CreateRepeaterPageMenu() must be added to Bind() to recreate the page index each time that the page number is changed - whether by selecting the page specifically or using the navigation button.
You made it so simple! Thank you for taking the time.
Hi there,
I am having some problems where when I click next it doesn’t load the next set of items for some reason. I have used the code exactly the same as your example. Any ideas?
Cheers,
Mel
THIS SAVED MY LIFE >> !! THANKS IT WORKS GREAT !!