前言:
也许你正用着:DataGrid/GridView自带的分页
也许你正用着:网上流传较广的AspnetPager分页控件
也许你正用着:其它同事写的分页控件
又也许:你正是那个写分页控件的人,如果是,现在的你是否回头看过自己当初的源码?感觉?
附言:
cs代码大小从原来的14K,缩减到4K。
原来的分页控件源码:点击下载
正文:
一:概述
目前分页控件,据个人所知的,有几下几种实现情况:
1:Post篇 [生成N个按钮,每个按钮点击时产生一个Post事件引发分页]
本文方式:反射机制,与sql无关。
遥想当年是配合了atlas的updatepanel实现的无刷新
2:Get篇 [生成N个链接,每个链接点击时产生一个Get事件引发分页]
方式二:链接分页,Url重写,常见于url参数为 /page/N
方式三:脚本分页,无刷新,链接都采用onclick="js函数"引发ajax回调异步分页。
二:实现
在具体写实现代码之前,我们上几张图片看一下效果:
说明:
所以样式是自己临时加上去的,大伙自己感知一下效果了就可以了。
下面开始分页控件实现具体步骤:
1:新建一个用户控件:Pager
2:控件前台html

<tr>
<td>
<asp:LinkButton ID="lbtnFirstLink" runat="server" CausesValidation="false" OnClick="ClickEvent">首页</asp:LinkButton>
<asp:LinkButton ID="lbtnPrevPage" runat="server" CausesValidation="false" OnClick="ClickEvent">上一页</asp:LinkButton>
<asp:Repeater ID="rptNum" runat="server" OnItemCommand="rptNum_ItemCommand">
<ItemTemplate>
<asp:LinkButton ID="lbtnNum" runat="server" CausesValidation="false" CommandArgument='<%# Container.DataItem %>'
CssClass='<%# Convert.ToInt32(Container.DataItem)==PageIndex?"num_yellow":"num_blue"%>' Width="15"><%# Container.DataItem %>
</ItemTemplate>
</asp:Repeater>
<asp:LinkButton ID="lbtnNextPage" runat="server" CausesValidation="false" OnClick="ClickEvent">下一页</asp:LinkButton>
<asp:LinkButton ID="lbtnLastPage" runat="server" CausesValidation="false" OnClick="ClickEvent">尾页</asp:LinkButton>
<asp:HiddenField ID="hfBindName" runat="server" />
</td>
</tr>
</table>
说明:
B:用了五个LinkButton,其中数字的一个用Repeater循环N个数字出来
C:最后加了一个隐藏域,用于保存绑定的方法名称。
3:后台cs代码
A:几个属性

public int PageIndex
{
get{if (_PageIndex == 0){ _PageIndex = 1;}return _PageIndex;}
set{ _PageIndex = value;}
}
private int _PageSize;
public int PageSize
{
get{if (_PageSize == 0){_PageSize = 1;}return _PageSize;}
set{ _PageSize = value;}
}
private int _Count;
public int Count
{
get{return _Count; }
set { _Count = value; }
}
/// <summary>
/// 该方法名称修饰符为需为public
/// </summary>
public string BindName
{
get{return hfBindName.Value;}
set{hfBindName.Value = value; }
}
说明:
PageSize:每页多少条
Count:记录总数
BindName:绑定的方法名称,用于反射绑定数据
B:Page_Load做点什么
{
if (!Page.IsPostBack)
{
BindPager();//绑定分页数字
}
}
说明:
C:绑定分页数字

{
int pageCount = (Count % PageSize) == 0 ? Count / PageSize : Count / PageSize + 1;//页数
SetButtonEnable(pageCount);//下面四个按钮可用状态设置
BindPageNum(pageCount);//绑定循环数字
}
说明:
2:根据当页的页数和当前页面索引,设置下“首页/下一页/上一页/尾页”的可用状态
3:根据当前的页数绑定一下循环的数字。
函数分解:SetButtonEnable [设置按钮可用状态及参数赋值]

{
lbtnFirstLink.Enabled = PageIndex != 1;
lbtnPrevPage.Enabled = PageIndex != 1;
lbtnNextPage.Enabled = PageIndex != pageCount;
lbtnLastPage.Enabled = PageIndex != pageCount;
lbtnFirstLink.CommandArgument = "1";
lbtnPrevPage.CommandArgument = (PageIndex - 1).ToString();
lbtnNextPage.CommandArgument = (PageIndex + 1).ToString();
lbtnLastPage.CommandArgument = pageCount.ToString();
}
说明:
2:如果当前页为最后1页:下一页/尾页状态不可用
3:顺路把几个页索引值赋给CommandArgument
函数分解:BindPageNum [绑定分页数字]

{
int start = 1, end = 10;
if (pageCount < end)//页数小于10
{
end = pageCount;
}
else
{
start = (PageIndex > 5) ? PageIndex - 5 : start;
int result = (start + 9) - pageCount;//是否超过最后面的页数
if (result > 0)
{
end = pageCount;
start -= result;//超过后,补差
}
else
{
end = start + 9;
}
}
ReBindNum(start, end);
}
说明:
2:根据开始数字和结束数字进行绑定
函数分解:ReBindNum [循环绑定数字]

{
int[] rows = new int[end-start+1];//这里之前写10,修正为end-start+1。
int index = 0;
for (int i = start; i <= end; i++)
{
rows[index] = i;
index++;
}
rptNum.DataSource = rows;
rptNum.DataBind();
}
说明:
2:界面绑定用<%# Container.DataItem %>方式进行对应
D:反射绑定[简洁重点函数]

{
PageIndex = int.Parse(pageIndex);
object obj = base.Parent is HtmlForm ? this.Page : base.Parent;
MethodInfo mi = obj.GetType().GetMethod(BindName);
mi.Invoke(obj,null);
BindPager();
}
说明:
2:获取绑定数据的方法,重新调用一下
3:重新绑定分布数字
F:首页/上一页/下一页/尾页,按钮事件
{
ReBindData(((LinkButton)sender).CommandArgument.ToString());
}
G:分页数字,按钮事件
{
ReBindData(e.CommandArgument.ToString());
}
三:示例代码,和 CYQ.Data轻量数据层框架 配合使用
1:html代码

<%@ Register Src="UserControls/Pager.ascx" TagName="Pager" TagPrefix="uc1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>路过秋天 分页控件演示</title>
<style type="text/css">
#pager {color:White;}
#pager a{color:White;text-decoration:none; }
.num_blue{color:White;border:solid 1px Blue;text-align:center;}
.num_yellow{color:while;border:solid 1px Yellow; text-align:center;}
</style>
</head>
<body style="background-color:Black;color:White;">
<form id="form1" runat="server">
<div><asp:GridView ID="gvUsers" runat="server"></asp:GridView><br />
<uc1:Pager ID="Pager1" runat="server" />
</div>
</form>
</body>
</html>
2:后台代码

{
if (!IsPostBack)
{
LoadData();
}
}
public void LoadData()
{
int count;
MAction action = new MAction(TableNames.Users);
MDataTable mTable = action.Select(Pager1.PageIndex, Pager1.PageSize, "", out count);
action.Close();
gvUsers.DataSource = mTable;
gvUsers.DataBind();
Pager1.BindName = "LoadData";
Pager1.Count = count;
}
说明:
2: 默认的分页PageSize可自行修改默认值
3: 前面html也可设置为:<uc1:Pager ID="Pager1" runat="server" PageSize="20" />
3:最终效果
结言:
有兴趣的来客欢迎讨论留言。
版权声明:本文原创发表于 博客园,作者为 路过秋天 本文欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则视为侵权。 |
个人微信公众号![]() |
Donation(扫码支持作者):支付宝:![]() |
Donation(扫码支持作者):微信:![]() |
![]() |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
· 上周热点回顾(2.17-2.23)