Ok, so during my time with Dot Net - which I love by the way - apart frrom when you want to do something slightly outside of DotNet logic - that...well thats when it get complicated
Anyway - I keep meaning to post something on my Blog every week but rarely get a chance to - been hellishly busy (good use of word hellishly there I thought).
So, something I find useful on occassion - PagedDataSource
Now, with the GridView approach (or DataGrid etc...) this is all build in and can be easily managed on the GridView control by simply adding AllowPaging=true - yes, it really is that simple, set a datasource to the gridview, bind it, allowpaging, set pagesize - theres enough properties available to keep you happy for hours.
The only real issue I have hear is styling the BACK and NEXT paging controls and the pages available. Its not 100% perfect in a GridView - it should be easier - really it should be - its not like you can't style it to your hearts content - but sometimes you just want that bit more customisation.
So - I give you the PagedDataSource and in this example the Repeater control.
############### Lets begin
Lets start with adding a Repeater control to the page and a Literal control which we will use to write a string value to show the end user what page they are on and how many pages there are.
<asp:Literal ID="lit_Pages" runat="server" />
<asp:Repeater ID="rpt" runat="server">
<ItemTemplate>
<!-- put your databound items in here -->
<%#Eval("A_Data_Bound_Item")%>
</ItemTemplate>
</asp:Repeater>
Easy - so now you need to bind your data to this control - lets go to the code behind for this :) Now, I normally used a class I created which controls PagedDateSources which I can call in any page and set a few properties, but in this example I will create a method which is called from the Page_Load method.
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not Page.IsPostBack Then
'is no post back occured
bindPagedDS() 'onlys runs at intial load of page
End If
End Sub
Once this is done you will need to add a property (could be a method if you wanted) to store the CURRENT page index that an end user is viewing, i.e. page 1 of 10
This is simple.
'a variable for the name of the item in ViewState that you will store CurrentPageIndex to.
Public pdsName As String = "ViewState_PagingSource_Name"
''' <summary>
''' Stores current page in repeater paging to viewstate
''' </summary>
''' <param name="vsName">String. Name of viewstate key.</param>
''' <value></value>
''' <returns>Integer. The current page number</returns>
''' <remarks></remarks>
Public Property CurrentPage(ByVal vsName As String) As Integer
Get
Dim o As Object = Me.ViewState(vsName)
If o Is Nothing Then
Return 0
Else
Return Convert.ToInt32(o)
End If
End Get
Set(ByVal value As Integer)
Me.ViewState(vsName) = value
End Set
End Property
''' <summary>
''' Creates PagedDataSource object
''' </summary>
''' <remarks></remarks>
Public Sub bindPagedDS()
Dim pds As New PagedDataSource
Dim dt as New DataTable
dt = A_Collection_Of_Data 'whatever you require this to be, a database create datatable, some XML, whatever
pds.DataSource = dt 'your data
pds.PageSize = "10" 'any integer you require
pds.CurrentPageIndex = Me.CurrentPage(pdsName) 'store the CurrentPageIndex in viewstate - nice
pds.AllowPaging = True 'yep, set paging on this bad boy
Me.cmdBack.Visible = Not pds.IsFirstPage 'if its NOT first page - which mean - if it is first page return TRUE so NOT TRUE is false :)
Me.cmdNext.Visible = Not pds.IsLastPage 'see above comment numbnuts
Me.lit_Pages.Text = (pds.CurrentPageIndex + 1) & " of " & pds.PageCount 'set text of Literal control to page info rpt.DataSource = pds 'set the Repeater data source to the PagedDataSource we have just created
rpt.DataBind() 'bind it stoooopid
End Sub
Right, now we have binded the data to the Repeater we know that we want a BACK and NEXT button which we can customise - so lets a couple ifLinkButtons onto the page at design level (can be any submit control - such as Button or ImageButton).
We also want to set the Command property on each LinkButton to called a custom method to handle the BACK and NEXT operations. I use this as its a method I can apply to both of the LinkButtons and action paging BACK or NEXT via a CommandArgument which for BACK is '-' (negative/minus symbol) and '+' (positive/add symbol)
<asp:LinkButton ID="lnkBtn_Back" runat="server" Text="<< Back" OnCommand="actionPaging" CommandArgument="-" />
|
<asp:LinkButton ID="lnkBtn_Next" runat="server" Text="Next >>" OnCommand="actionPaging" CommandArgument="+" />
Once we have added this to the LinkButton controls at design level we are ready to add a method to handle the Command for each of them. So, in the code behind add another method:
''' <summary>
''' Actions a paging request. BACK or NEXT page
''' </summary>
''' <param name="sender">LinkButton. The control clicked,.</param>
''' <param name="e">CommandEventArgs. Command event arguments.</param>
''' <remarks></remarks>
Public Sub actionPaging(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.CommandEventArgs)
'now we must check what the CommandArgument value is and perform a increment or subtraction accordinly
If e.CommandArgument = "-" Then
'is back on page - MINUS
Me.CurrentPage(pdsName) -= 1 'store the NEW page number in viewstate
Else
'assume next page - ADD
Me.CurrentPage(pdsName) += 1 'store the NEW page number in viewstate
End If
'this method can only occur on postback so now we re-bind the data
bindPagedDS() 'now rebind the data dummy :)
End Sub
############### Thats it
Pretty easy hey - I have only covered the PagedDataSource in as a quick guide to getting you started - just allows for ease of customisation over GridViews - and look into caching the data to improve performance (unless you will be updating records in this view - in which case why aren't you using a GridView ;-) )