当前位置: 移动技术网 > IT编程>开发语言>.net > asp.net中让Repeater和GridView支持DataPager分页

asp.net中让Repeater和GridView支持DataPager分页

2017年12月12日  | 移动技术网IT编程  | 我要评论

瘤鸭,徐金烨,四川爱华航空学院

改造办法是自己写一个控件,让它继承gridview或repeater,并实现ipageableitemcontainer 接口。下面要发的是国外某高手写的代码,测试有效。具体使用的时候,要建一个类库项目,把代码编译成dll后,就可以添加到vs的工具箱里了!
一、自定义repeater
复制代码 代码如下:

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 should 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 (isboundusingdatasourceid == false && !page.ispostback)
return true;
if (isboundusingdatasourceid == 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 (!isboundusingdatasourceid && persistentdatasource && viewstate["datasource"] != null)
// {
// this.datasource = viewstate["datasource"];
// this.databind(true);
// }
// if (isboundusingdatasourceid)
// {
// 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 (!isboundusingdatasourceid && persistentdatasource && viewstate["datasource"] != null)
{
this.datasource = viewstate["datasource"];
this.databind();
}
if (isboundusingdatasourceid)
{
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 || isboundusingdatasourceid)
{
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 (!isboundusingdatasourceid && 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;
}
}

aspx页面要做的事情(以我网站的留言板为例):
首先得把标签注册进来
复制代码 代码如下:
<%@ register assembly="wyj.web.controls" namespace="wyj.web.controls" tagprefix="wyj" %>

然后添加我们的repeater
复制代码 代码如下:

<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></h2>
<div class="lvwordcontent">
<%# ((geekstudio.orm.model.leaveword)container.dataitem).content %>
</div>
</div>
</div>
</itemtemplate>
</wyj:datapagerrepeater>

之后添加.net自带的datapager,并自定义一些分页样式
复制代码 代码如下:

<div class="pager">
<div class="fr">
共<%=math.ceiling((double)datapager1.totalrowcount / datapager1.pagesize)%>页,<%=datapager1.totalrowcount%>条记录,每页显示
<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="首页" />
<asp:nextpreviouspagerfield shownextpagebutton="false" buttontype="image" previouspageimageurl="~/images/icons/pagerprevious.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="尾页" />
</fields>
</asp:datapager>
</div>

后台代码:
分页部分不需要代码。下面发的代码是切换每页显示数量的:
复制代码 代码如下:

protected void lnkbtn10_click(object sender, eventargs e)
{
datapager1.pagesize = 10;
lnkbtn10.cssclass = "currentpagesize";
lnkbtn20.cssclass = "";
lnkbtn30.cssclass = "";
}
protected void lnkbtn20_click(object sender, eventargs e)
{
datapager1.pagesize = 20;
lnkbtn20.cssclass = "currentpagesize";
lnkbtn10.cssclass = "";
lnkbtn30.cssclass = "";
}
protected void lnkbtn30_click(object sender, eventargs e)
{
datapager1.pagesize = 30;
lnkbtn30.cssclass = "currentpagesize";
lnkbtn10.cssclass = "";
lnkbtn20.cssclass = "";
}

二、自定义gridview
复制代码 代码如下:

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 cancelled 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);
}
}
}
}

用法与repeater类似,不多发了~

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网