The transformation method is to write a control by yourself, let it inherit the GridView or Repeater, and implement the IPageableItemContainer interface. The following is a highly handwritten code from abroad, which is valid for testing. In actual use, you need to create a class library project. After compiling the code into a dll, you can add it to the VS toolbox!
1. Custom Repeater
Copy codeThe Code is as follows: using System. Web. UI;
Using System. Web. UI. WebControls;
Namespace WYJ. Web. Controls
{
/// <Summary>
/// Repeater with support for DataPager
/// </Summary>
[ToolboxData ("<{0}: DataPagerRepeater runat = server PersistentDataSource = true> </{0}: DataPagerRepeater>")]
Public class DataPagerRepeater: Repeater, System. Web. UI. WebControls. IPageableItemContainer, INamingContainer
{
/// <Summary>
/// Number of rows to show
/// </Summary>
Public int MaximumRows {get {return ViewState ["MaximumRows"]! = Null? (Int) ViewState ["MaximumRows"]:-1 ;}}
/// <Summary>
/// First row to show
/// </Summary>
Public int StartRowIndex {get {return ViewState ["StartRowIndex"]! = Null? (Int) ViewState ["StartRowIndex"]:-1 ;}}
/// <Summary>
/// Total rows. When PagingInDataSource is set to true you must get the total records from the datasource (without paging) at the FetchingData event
/// When PagingInDataSource is set to true you also need to set this when you load the data the first time.
/// </Summary>
Public int TotalRows {get {return ViewState ["TotalRows"]! = Null? (Int) ViewState ["TotalRows"]:-1 ;}set {ViewState ["TotalRows"] = value ;}}
/// <Summary>
/// If repeater shocould store data source in view state. If false you need to get and bind data at post back. When using a connected data source this is handled by the data source.
/// </Summary>
Public bool PersistentDataSource
{
Get {return ViewState ["PersistentDataSource"]! = Null? (Bool) ViewState ["PersistentDataSource"]: true ;}
Set {ViewState ["PersistentDataSource"] = value ;}
}
/// <Summary>
/// Set to true if you want to handle paging in the data source.
/// Ex if you are selecting data from the database and only select the current rows
/// You must set this property to true and get and rebind data at the FetchingData event.
/// If this is true you must also set the TotalRecords property at the FetchingData event.
/// </Summary>
/// <Seealso cref = "FetchingData"/>
/// <Seealso cref = "TotalRows"/>
Public bool PagingInDataSource
{
Get {return ViewState ["PageingInDataSource"]! = Null? (Bool) ViewState ["PageingInDataSource"]: false ;}
Set {ViewState ["PageingInDataSource"] = value ;}
}
/// <Summary>
/// Checks if you need to rebind data source at postback
/// </Summary>
Public bool NeedsDataSource
{
Get
{
If (PagingInDataSource)
Return true;
If (isboundusingperformanceid = false &&! Page. IsPostBack)
Return true;
If (isboundusingperformanceid = false & PersistentDataSource = false & Page. IsPostBack)
Return true;
Else
Return false;
}
}
/// <Summary>
/// Loading ViewState
/// </Summary>
/// <Param name = "savedState"> </param>
Protected override void LoadViewState (object savedState)
{
Base. LoadViewState (savedState );
// If (Page. IsPostBack)
//{
// If (! Isboundusingperformanceid & PersistentDataSource & ViewState ["DataSource"]! = Null)
//{
// This. DataSource = ViewState ["DataSource"];
// This. DataBind (true );
//}
// If (isboundusingperformanceid)
//{
// This. DataBind ();
//}
//}
}
Protected override void OnLoad (System. EventArgs e)
{
If (Page. IsPostBack)
{
If (NeedsDataSource & FetchingData! = Null)
{
If (PagingInDataSource)
{
SetPageProperties (StartRowIndex, MaximumRows, true );
}
FetchingData (this, null );
}
If (! Isboundusingperformanceid & PersistentDataSource & ViewState ["DataSource"]! = Null)
{
This. DataSource = ViewState ["DataSource"];
This. DataBind ();
}
If (isboundusingperformanceid)
{
This. DataBind ();
}
}
Base. OnLoad (e );
}
/// <Summary>
/// Method used by pager to set totalrecords
/// </Summary>
/// <Param name = "startRowIndex"> startRowIndex </param>
/// <Param name = "maximumRows"> maximumRows </param>
/// <Param name = "databind"> databind </param>
Public void SetPageProperties (int startRowIndex, int maximumRows, bool databind)
{
ViewState ["StartRowIndex"] = startRowIndex;
ViewState ["MaximumRows"] = maximumRows;
If (TotalRows>-1)
{
If (TotalRowCountAvailable! = Null)
{
TotalRowCountAvailable (this, new PageEventArgs (int) ViewState ["StartRowIndex"], (int) ViewState ["MaximumRows"], TotalRows ));
}
}
}
/// <Summary>
/// OnDataPropertyChanged
/// </Summary>
Protected override void OnDataPropertyChanged ()
{
If (MaximumRows! =-1 | isboundusingperformanceid)
{
This. RequiresDataBinding = true;
}
Base. OnDataPropertyChanged ();
}
/// <Summary>
/// Renders only current items selected by pager
/// </Summary>
/// <Param name = "writer"> </param>
Protected override void RenderChildren (HtmlTextWriter writer)
{
If (! PagingInDataSource & MaximumRows! =-1)
{
Foreach (RepeaterItem item in this. Items)
{
If (item. ItemType = ListItemType. Item | item. ItemType = ListItemType. AlternatingItem)
{
Item. Visible = false;
If (item. itemIndex> = (int) ViewState ["StartRowIndex"] & item. itemIndex <(int) ViewState ["StartRowIndex"] + (int) ViewState ["MaximumRows"])
{
Item. Visible = true;
}
}
Else
{
Item. Visible = true;
}
}
}
Base. RenderChildren (writer );
}
/// <Summary>
/// Get Data
/// </Summary>
/// <Returns> </returns>
Protected override System. Collections. IEnumerable GetData ()
{
System. Collections. IEnumerable dataObjects = base. GetData ();
If (dataObjects = null & this. DataSource! = Null)
{
If (this. DataSource is System. Collections. IEnumerable)
DataObjects = (System. Collections. IEnumerable) this. DataSource;
Else
DataObjects = (System. ComponentModel. IListSource) this. DataSource). GetList ();
}
If (! PagingInDataSource & MaximumRows! =-1 & dataObjects! = Null)
{
Int I =-1;
If (dataObjects! = Null)
{
I = 0;
Foreach (object o in dataObjects)
{
I ++;
}
}
ViewState ["TotalRows"] = I;
If (! Isboundusingperformanceid & PersistentDataSource)
ViewState ["DataSource"] = this. DataSource;
SetPageProperties (StartRowIndex, MaximumRows, true );
}
If (PagingInDataSource &&! Page. IsPostBack)
{
SetPageProperties (StartRowIndex, MaximumRows, true );
}
Return dataObjects;
}
/// <Summary>
/// Event when pager/repeater have counted total rows
/// </Summary>
Public event System. EventHandler <PageEventArgs> TotalRowCountAvailable;
/// <Summary>
/// Event when repeater gets the data on postback
/// </Summary>
Public event System. EventHandler <PageEventArgs> FetchingData;
}
}
What to do on the ASPX page (take the message board on my website as an example ):
First, register the tag.Copy codeThe Code is as follows: <% @ Register Assembly = "WYJ. Web. Controls" Namespace = "WYJ. Web. Controls" TagPrefix = "WYJ" %>
Then add our RepeaterCopy codeThe Code is as follows: <WYJ: DataPagerRepeater ID = "rptLeaveword" runat = "server" PersistentDataSource = "true">
<ItemTemplate>
<Div class = "leavewordentry">
<Div class = "datebox">
<Div class = "time">
<% # (GeekStudio. ORM. Model. Leaveword) Container. DataItem). Posttime. ToString ("HH: mm") %> </div>
<Div class = "day">
<% # (GeekStudio. ORM. Model. Leaveword) Container. DataItem). Posttime. ToString ("dd") %>
</Div>
<Div class = "month">
<% # (GeekStudio. ORM. model. leaveword) Container. dataItem ). posttime. toString ("MMM", new CultureInfo ("en-US ")). toUpper () %> <% # (GeekStudio. ORM. model. leaveword) Container. dataItem ). posttime. toString ("yyyy") %> </div>
</Div>
<Div class = "contentbox">
<H2 class = "username">
<A id = "<% # GeekStudio. Common. IdEncryptor. EncodeId (GeekStudio. ORM. Model. Leaveword) Container. DataItem). Id) %>"
Name = "<% # GeekStudio. Common. IdEncryptor. EncodeId (GeekStudio. ORM. Model. Leaveword) Container. DataItem). Id) %>">
<% # (GeekStudio. ORM. Model. Leaveword) Container. DataItem). Username %> </a> <Div class = "lvwordcontent">
<% # (GeekStudio. ORM. Model. Leaveword) Container. DataItem). Content %>
</Div>
</Div>
</Div>
</ItemTemplate>
</WYJ: DataPagerRepeater>
Add the DataPager that comes with. NET and customize some paging styles.Copy codeThe Code is as follows: <div class = "pager">
<Div class = "fr">
Total <% = Math. Ceiling (double) DataPager1.TotalRowCount/DataPager1.PageSize) %> pages, <% = DataPager1.TotalRowCount %> records, displayed on each page
<Asp: LinkButton ID = "lnkbtn10" CssClass = "currentpagesize" runat = "server" OnClick = "lnkbtn10_Click"> 10 </asp: LinkButton>
<Asp: LinkButton ID = "lnkbtn20" runat = "server" OnClick = "lnkbtn20_Click"> 20 </asp: LinkButton>
<Asp: LinkButton ID = "lnkbtn30" runat = "server" OnClick = "lnkbtn30_Click"> 30 </asp: LinkButton>
</Div>
<Asp: DataPager ID = "DataPager1" PagedControlID = "rptLeaveword" runat = "server">
<Fields>
<Asp: NextPreviousPagerField ShowFirstPageButton = "True" ShowNextPageButton = "False"
ShowPreviousPageButton = "False" FirstPageText = "Homepage"/>
<Asp: NextPreviousPagerField ShowNextPageButton = "False" ButtonType = "Image" PreviousPageImageUrl = "~ /Images/icons/pagerprevius.png "/>
<Asp: NumericPagerField CurrentPageLabelCssClass = "current"/>
<Asp: NextPreviousPagerField ShowPreviousPageButton = "False" ButtonType = "Image" NextPageImageUrl = "~ /Images/icons/pagernext.png "/>
<Asp: NextPreviousPagerField ShowLastPageButton = "True" ShowNextPageButton = "False"
ShowPreviousPageButton = "False" LastPageText = "last page"/>
</Fields>
</Asp: DataPager>
</Div>
Background code:
Code is not required for the paging part. The following code switches the number displayed on each page:Copy codeThe Code is as follows: protected void lnkbtn10_Click (object sender, EventArgs e)
{
DataPager1.PageSize = 10;
Lnkbtn10.CssClass = "currentpagesize ";
Lnkbtn1_cssclass = "";
Lnkbtn30.CssClass = "";
}
Protected void lnkbtn20_Click (object sender, EventArgs e)
{
DataPager1.PageSize = 20;
Lnkbtn1_cssclass = "currentpagesize ";
Lnkbtn10.CssClass = "";
Lnkbtn30.CssClass = "";
}
Protected void lnkbtn30_Click (object sender, EventArgs e)
{
DataPager1.PageSize = 30;
Lnkbtn30.CssClass = "currentpagesize ";
Lnkbtn10.CssClass = "";
Lnkbtn1_cssclass = "";
}
Ii. Custom GridViewCopy codeThe Code is as follows: using System;
Using System. Collections;
Using System. Web. UI. WebControls;
Namespace WYJ. Web. Controls
{
/// <Summary>
/// DataPagerGridView is a custom control that implements GrieView and IPageableItemContainer
/// </Summary>
Public class DataPagerGridView: GridView, IPageableItemContainer
{
Public DataPagerGridView ()
: Base ()
{
PagerSettings. Visible = false;
}
/// <Summary>
/// TotalRowCountAvailable event key
/// </Summary>
Private static readonly object EventTotalRowCountAvailable = new object ();
/// <Summary>
// Call base control's CreateChildControls method and determine the number of rows in the source
/// Then fire off the event with the derived data and then we return the original result.
/// </Summary>
/// <Param name = "dataSource"> </param>
/// <Param name = "dataBinding"> </param>
/// <Returns> </returns>
Protected override int CreateChildControls (IEnumerable dataSource, bool dataBinding)
{
Int rows = base. CreateChildControls (dataSource, dataBinding );
// If the paging feature is enabled, determine the total number of rows in the datasource
If (this. AllowPaging)
{
// If we are databinding, use the number of rows that were created, otherwise cast the datasource to an Collection and use that as the count
Int totalRowCount = dataBinding? Rows: (ICollection) dataSource). Count;
// Raise the row count available event
IPageableItemContainer pageableItemContainer = this as IPageableItemContainer;
This. OnTotalRowCountAvailable (new PageEventArgs (pageableItemContainer. StartRowIndex, pageableItemContainer. MaximumRows, totalRowCount ));
// Make sure the top and bottom pager rows are not visible
If (this. TopPagerRow! = Null)
This. TopPagerRow. Visible = false;
If (this. BottomPagerRow! = Null)
This. BottomPagerRow. Visible = false;
}
Return rows;
}
/// <Summary>
/// Set the control with appropriate parameters and bind to right chunk of data.
/// </Summary>
/// <Param name = "startRowIndex"> </param>
/// <Param name = "maximumRows"> </param>
/// <Param name = "databind"> </param>
Void IPageableItemContainer. SetPageProperties (int startRowIndex, int maximumRows, bool databind)
{
Int newPageIndex = (startRowIndex/maximumRows );
This. PageSize = maximumRows;
If (this. PageIndex! = NewPageIndex)
{
Bool isCanceled = false;
If (databind)
{
// Create the event arguments and raise the event
GridViewPageEventArgs args = new GridViewPageEventArgs (newPageIndex );
This. OnPageIndexChanging (args );
IsCanceled = args. Cancel;
NewPageIndex = args. NewPageIndex;
}
// If the event wasn' t canceled change the paging values
If (! IsCanceled)
{
This. PageIndex = newPageIndex;
If (databind)
This. OnPageIndexChanged (EventArgs. Empty );
}
If (databind)
This. RequiresDataBinding = true;
}
}
/// <Summary>
/// IPageableItemContainer's StartRowIndex = PageSize * PageIndex properties
/// </Summary>
Int IPageableItemContainer. StartRowIndex
{
Get {return this. PageSize * this. PageIndex ;}
}
/// <Summary>
/// IPageableItemContainer's MaximumRows = PageSize property
/// </Summary>
Int IPageableItemContainer. MaximumRows
{
Get {return this. PageSize ;}
}
/// <Summary>
///
/// </Summary>
Event EventHandler <PageEventArgs> IPageableItemContainer. TotalRowCountAvailable
{
Add {base. Events. AddHandler (DataPagerGridView. EventTotalRowCountAvailable, value );}
Remove {base. Events. RemoveHandler (DataPagerGridView. EventTotalRowCountAvailable, value );}
}
/// <Summary>
///
/// </Summary>
/// <Param name = "e"> </param>
Protected virtual void OnTotalRowCountAvailable (PageEventArgs e)
{
EventHandler <PageEventArgs> handler = (EventHandler <PageEventArgs>) base. Events [DataPagerGridView. EventTotalRowCountAvailable];
If (handler! = Null)
{
Handler (this, e );
}
}
}
}
Similar to Repeater, no more ~