Web用户控件开发--分页控件
分页是Web应用程序中最常用到的功能之一,在ASP.NET中,虽然自带了一些可以分页的数据控件,但其分页功能并不尽如人意。本文对于这些数据控件的假分页暂且不表,如有不明白的同学请百Google度之。
本文中实现的分页控件是在手动分页基础上做的改善,将分页实现的逻辑部分和数据控件的绑定尽可能分开,以克服手工编写分页代码任务繁琐、代码重用率低等问题。
本文依旧是一粒粟子。
一、分页控件素颜
二、分页控件的实现
本文中将介绍两种将分页实现逻辑与数据控件绑定分离的实现方式:
- 使用反射机制
- 使用事件机制
1、基于反射机制的分页控件
源码:
PagingHelper.ascx:
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="PagingHelper.ascx.cs" Inherits="PagingHelper.Controls.PagingHelper" %>
<div style="width:100%">
<asp:LinkButton ID="lbtnFirstPage" runat="server" CausesValidation="false" onclick="lbtnPage_Click" >首页</asp:LinkButton>
<asp:LinkButton ID="lbtnPrevPage" runat="server" CausesValidation="false" onclick="lbtnPage_Click" >上一页</asp:LinkButton>
第<asp:Label ID="lbPageIndex" runat="server" Text=""></asp:Label>
页/共<asp:Label ID="lbTotalPages" runat="server" Text=""></asp:Label>
页
<asp:LinkButton ID="lbtnNextPage" runat="server" CausesValidation="false" onclick="lbtnPage_Click" >下一页</asp:LinkButton>
<asp:LinkButton ID="lbtnLastPage" runat="server" CausesValidation="false" onclick="lbtnPage_Click" >尾页</asp:LinkButton>
</div>
PagingHelper.ascx.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Reflection;
namespace PagingHelper.Controls
{
public partial class PagingHelper : System.Web.UI.UserControl
{
#region 属性
private int m_PageSize;
public int PageSize //每页显示记录数
{
set
{
m_PageSize = value;
}
get
{
if (m_PageSize.Equals(0))
{
m_PageSize = 10;
}
return m_PageSize;
}
}
private int m_PageIndex;
public int PageIndex //当前页页码
{
set
{
m_PageIndex = value;
}
get
{
if (m_PageIndex.Equals(0))
{
m_PageIndex = 1;
}
return m_PageIndex;
}
}
public int TotalItemCount //记录总数
{
set;
private get;
}
public string BindDataMethodName //绑定数据的方法名
{
set;
private get;
}
#endregion
#region 受保护的方法
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
BindPagingHelperControl();
}
}
protected void lbtnPage_Click(object sender, EventArgs e)
{
LinkButton lbtn = sender as LinkButton;
ReBindData(lbtn.CommandArgument);
}
#endregion
#region 公共方法
#endregion
#region 私有方法
private void BindPagingHelperControl()
{
int totalPages = (TotalItemCount % PageSize) == 0 ? TotalItemCount / PageSize : TotalItemCount / PageSize + 1;
//显示
lbPageIndex.Text = PageIndex.ToString();
lbTotalPages.Text = totalPages.ToString();
//使能
lbtnFirstPage.Enabled = PageIndex > 1;
lbtnPrevPage.Enabled = PageIndex > 1;
lbtnLastPage.Enabled = PageIndex < totalPages;
lbtnNextPage.Enabled = PageIndex < totalPages;
//命令
lbtnFirstPage.CommandArgument = "1";
lbtnPrevPage.CommandArgument = (PageIndex - 1).ToString();
lbtnNextPage.CommandArgument = (PageIndex + 1).ToString();
lbtnLastPage.CommandArgument = totalPages.ToString();
}
private void ReBindData(string pageIndex)
{
PageIndex = int.Parse(pageIndex);
Object obj = null; //空间所在的容器
if (base.Parent is HtmlForm)
{
obj = this.Page;
}
else if (base.Parent is ContentPlaceHolder)
{
obj = this.Page.Master.Page;
}
else
{
obj = base.Parent;
}
MethodInfo methodInfo = obj.GetType().GetMethod(BindDataMethodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
methodInfo.Invoke(obj, null);
BindPagingHelperControl();
}
#endregion
}
}
Demo:
Default.aspx:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="PagingHelper.Default" %>
<%@ Register src="Controls/PagingHelper.ascx" tagname="PagingHelper" 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>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:GridView ID="gvDemo" runat="server">
</asp:GridView>
<br />
<uc1:PagingHelper ID="PagingHelper1" runat="server" PageSize="2" />
</div>
</form>
</body>
</html>
Default.aspx.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
namespace PagingHelper
{
public partial class Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
GvDemoBind();
}
protected void GvDemoBind()
{
string sql = @"SELECT * FROM tb_user";
string sqlCount = @"SELECT COUNT(*) FROM tb_user ";
int itemStart = (PagingHelper1.PageIndex - 1) * PagingHelper1.PageSize;
sql += string.Format(" LIMIT {0},{1}",itemStart,PagingHelper1.PageSize);
gvDemo.DataSource = SQLHelper.ExecuteDataTable(sql).DefaultView;
gvDemo.DataBind();
PagingHelper1.TotalItemCount = Convert.ToInt32(SQLHelper.ExecuteScalar(sqlCount));
PagingHelper1.BindDataMethodName = "GvDemoBind";
}
}
}
2、基于事件机制的分页控件
源码:
PagingHelper.ascx:
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="PagingHelper.ascx.cs" Inherits="PagingHelper_V2.Controls.PagingHelper" %>
<div style="width:100%">
<asp:LinkButton ID="lbtnFirstPage" runat="server" CausesValidation="false" onclick="lbtnPage_Click" >首页</asp:LinkButton>
<asp:LinkButton ID="lbtnPrevPage" runat="server" CausesValidation="false" onclick="lbtnPage_Click" >上一页</asp:LinkButton>
第<asp:Label ID="lbPageIndex" runat="server" Text=""></asp:Label>
页/共<asp:Label ID="lbTotalPages" runat="server" Text=""></asp:Label>
页
<asp:LinkButton ID="lbtnNextPage" runat="server" CausesValidation="false" onclick="lbtnPage_Click" >下一页</asp:LinkButton>
<asp:LinkButton ID="lbtnLastPage" runat="server" CausesValidation="false" onclick="lbtnPage_Click" >尾页</asp:LinkButton>
转到
<asp:TextBox ID="txtGoto" runat="server" Width="32px"></asp:TextBox>
页<asp:Button ID="btnGoto" runat="server" Text="确定" onclick="btnGoto_Click" />
</div>
PagingHelper.ascx.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
namespace PagingHelper_V2.Controls
{
public partial class PagingHelper : System.Web.UI.UserControl
{
#region 属性
private int m_PageSize;
public int PageSize //每页显示记录数
{
set
{
m_PageSize = value;
}
get
{
if (m_PageSize.Equals(0))
{
m_PageSize = 10;
}
return m_PageSize;
}
}
private int m_PageIndex;
public int PageIndex //当前页页码
{
set
{
m_PageIndex = value;
}
get
{
if (m_PageIndex.Equals(0))
{
m_PageIndex = 1;
}
return m_PageIndex;
}
}
public int TotalItemCount //记录总数
{
set;
private get;
}
#endregion
#region 受保护的方法
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
BindPagingHelperControl();
}
}
protected void lbtnPage_Click(object sender, EventArgs e)
{
LinkButton lbtn = sender as LinkButton;
ReBindData(int.Parse(lbtn.CommandArgument));
}
protected void btnGoto_Click(object sender, EventArgs e)
{
int gotoPageIndex = PageIndex;
if (int.TryParse(txtGoto.Text, out gotoPageIndex))
{
if (gotoPageIndex < 1 || gotoPageIndex > int.Parse(lbTotalPages.Text))
{
Response.Write("<script>alert('此页面不存在!')</script>");
}
else
{
if (!gotoPageIndex.Equals(int.Parse(lbPageIndex.Text)))
{
ReBindData(gotoPageIndex);
}
}
}
else
{
Response.Write("<script>alert('请输入正确的页码!')</script>");
}
}
#endregion
#region 公共方法
#endregion
#region 私有方法
private void BindPagingHelperControl()
{
int totalPages = (TotalItemCount % PageSize) == 0 ? TotalItemCount / PageSize : TotalItemCount / PageSize + 1;
//显示
lbPageIndex.Text = PageIndex.ToString();
lbTotalPages.Text = totalPages.ToString();
txtGoto.Text = PageIndex.ToString();
//使能
lbtnFirstPage.Enabled = PageIndex > 1;
lbtnPrevPage.Enabled = PageIndex > 1;
lbtnLastPage.Enabled = PageIndex < totalPages;
lbtnNextPage.Enabled = PageIndex < totalPages;
//命令
lbtnFirstPage.CommandArgument = "1";
lbtnPrevPage.CommandArgument = (PageIndex - 1).ToString();
lbtnNextPage.CommandArgument = (PageIndex + 1).ToString();
lbtnLastPage.CommandArgument = totalPages.ToString();
}
private void ReBindData(int pageIndex)
{
PageIndex = pageIndex;
OnPageIndexChanged(new EventArgs());
BindPagingHelperControl();
}
#endregion
#region 事件
public delegate void PageIndexChangedEventHandler(object sender, EventArgs e);
public event PageIndexChangedEventHandler PageIndexChanged;
protected virtual void OnPageIndexChanged(EventArgs e)
{
PageIndexChangedEventHandler handler = PageIndexChanged;
if (handler != null)
{
handler(this, e);
}
}
#endregion
}
}
Demo:
Default.aspx:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="PagingHelper_V2.Default" %>
<%@ Register src="Controls/PagingHelper.ascx" tagname="PagingHelper" 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>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:GridView ID="gvDemo" runat="server">
</asp:GridView>
<uc1:PagingHelper ID="PagingHelper1" runat="server" PageSize="2" OnPageIndexChanged="PagingHelper1_OnPageIndexChanged" />
</div>
</form>
</body>
</html>
Default.aspx.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace PagingHelper_V2
{
public partial class Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
GvDemoBind();
}
protected void GvDemoBind()
{
string sql = @"SELECT * FROM tb_user";
string sqlCount = @"SELECT COUNT(*) FROM tb_user ";
int itemStart = (PagingHelper1.PageIndex - 1) * PagingHelper1.PageSize;
sql += string.Format(" LIMIT {0},{1}", itemStart, PagingHelper1.PageSize);
gvDemo.DataSource = SQLHelper.ExecuteDataTable(sql).DefaultView;
gvDemo.DataBind();
PagingHelper1.TotalItemCount = Convert.ToInt32(SQLHelper.ExecuteScalar(sqlCount));
}
protected void PagingHelper1_OnPageIndexChanged(object sender, EventArgs e)
{
GvDemoBind();
}
}
}
三、总结
比较两种实现方式,基于事件机制的实现更符合ASP.NET服务器控件的style。
好!那就参照园子里的分页使用基于事件机制的方式再做一个控件作为总结。
源码:
PagingHelper.ascx:
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="PagingHelper.ascx.cs" Inherits="PagingHelper_V3.Controls.PagingHelper" %>
<style type="text/css">
a.LinkButtonDefault{text-align:center;text-decoration:none;margin-right:1px;padding:2px 4px;}
a.LinkButtonBlue{background: #ebebeb;text-align:center;text-decoration:none;margin-right:1px;padding:2px 4px;}
a.LinkButtonYellow { background-color:#ccc; color:#000fff; font-weight:bold;text-align:center;text-decoration:none;margin-right:1px;padding:2px 4px;}
</style>
<div style="width:100%">
共<asp:Label ID="lbTotalPages" runat="server" ForeColor="#fff"></asp:Label>页:
<asp:LinkButton ID="lbtnFirstPage" runat="server" CausesValidation="false" CssClass="LinkButtonDefault" onclick="lbtnPage_Click" >首页</asp:LinkButton>
<asp:LinkButton ID="lbtnPrevPage" runat="server" CausesValidation="false" CssClass="LinkButtonDefault" onclick="lbtnPage_Click" >上一页</asp:LinkButton>
<asp:Repeater ID="rptPageNumber" runat="server">
<ItemTemplate>
<asp:LinkButton ID="lbtnPageNumber" runat="server" CausesValidation="false" Width="16px" onclick="lbtnPage_Click"
CssClass='<%# Convert.ToInt32(Container.DataItem)==PageIndex?"LinkButtonYellow":"LinkButtonBlue"%>' CommandArgument='<%# Container.DataItem %>'>
<%
1: #Container.DataItem
%>
</asp:LinkButton>
</ItemTemplate>
</asp:Repeater>
<asp:LinkButton ID="lbtnNextPage" runat="server" CausesValidation="false" CssClass="LinkButtonDefault" onclick="lbtnPage_Click" >下一页</asp:LinkButton>
<asp:LinkButton ID="lbtnLastPage" runat="server" CausesValidation="false" CssClass="LinkButtonDefault" onclick="lbtnPage_Click" >尾页</asp:LinkButton>
</div>
PagingHelper.ascx.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace PagingHelper_V3.Controls
{
public partial class PagingHelper : System.Web.UI.UserControl
{
#region 属性
private int m_PageSize;
public int PageSize //每页显示记录数
{
set
{
m_PageSize = value;
}
get
{
if (m_PageSize.Equals(0))
{
m_PageSize = 10;
}
return m_PageSize;
}
}
private int m_PageIndex;
public int PageIndex //当前页页码
{
set
{
m_PageIndex = value;
}
get
{
if (m_PageIndex.Equals(0))
{
m_PageIndex = 1;
}
return m_PageIndex;
}
}
public int TotalItemCount //记录总数
{
set;
private get;
}
#endregion
#region 受保护的方法
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
BindPagingHelperControl();
}
}
protected void lbtnPage_Click(object sender, EventArgs e)
{
LinkButton lbtn = sender as LinkButton;
ReBindData(int.Parse(lbtn.CommandArgument));
}
#endregion
#region 公共方法
#endregion
#region 私有方法
private void BindPageNum(int totalPages)
{
int startPageIndex = 1, endPageIndex = 10;
if (totalPages < endPageIndex)
{
endPageIndex = totalPages;
}
else
{
startPageIndex = (PageIndex > 5) ? PageIndex - 5 : startPageIndex;
int result = (startPageIndex + 9) - totalPages;
if (result > 0)
{
endPageIndex = totalPages;
startPageIndex -= result;
}
else
{
endPageIndex = startPageIndex + 9;
}
}
BindPageNum(startPageIndex, endPageIndex);
}
private void BindPageNum(int startPageIndex, int endPageIndex)
{
int[] pages = new int[endPageIndex - startPageIndex + 1];
int index = 0;
for (int i = startPageIndex; i <= endPageIndex; i++)
{
pages[index] = i;
index++;
}
rptPageNumber.DataSource = pages;
rptPageNumber.DataBind();
}
private void BindPagingHelperControl()
{
int totalPages = (TotalItemCount % PageSize) == 0 ? TotalItemCount / PageSize : TotalItemCount / PageSize + 1;
//显示
lbTotalPages.Text = totalPages.ToString();
BindPageNum(totalPages);
//使能
lbtnFirstPage.Enabled = PageIndex > 1;
lbtnPrevPage.Enabled = PageIndex > 1;
lbtnLastPage.Enabled = PageIndex < totalPages;
lbtnNextPage.Enabled = PageIndex < totalPages;
//命令
lbtnFirstPage.CommandArgument = "1";
lbtnPrevPage.CommandArgument = (PageIndex - 1).ToString();
lbtnNextPage.CommandArgument = (PageIndex + 1).ToString();
lbtnLastPage.CommandArgument = totalPages.ToString();
}
private void ReBindData(int pageIndex)
{
PageIndex = pageIndex;
OnPageIndexChanged(new EventArgs());
BindPagingHelperControl();
}
#endregion
#region 事件
public delegate void PageIndexChangedEventHandler(object sender, EventArgs e);
public event PageIndexChangedEventHandler PageIndexChanged;
protected virtual void OnPageIndexChanged(EventArgs e)
{
PageIndexChangedEventHandler handler = PageIndexChanged;
if (handler != null)
{
handler(this, e);
}
}
#endregion
}
}
Web用户控件开发--分页控件的更多相关文章
- jQuery控件之分页控件-- kkpager v1.3使用简介
js分页展示控件,传入简单参数就能使用的分页效果控件 在线测试链接: http://pgkk.github.io/kkpager/example/pager_test.html http://pgkk ...
- DEV控件的分页控件,实现勾选复选框
/// <summary> /// 单元格的点击事件 /// </summary> /// <param name="sender"></ ...
- 用C#编写ActiveX控件,开发浏览器控件,注册ActiveX 控件
用C#编写ActiveX控件,开发浏览器控件,注册ActiveX 控件用C#编写ActiveX控件 开发浏览器控件这是本控件开发完成后的一个简单应用.我们可以利用它以本地文件夹为单位来批量更新服务器的 ...
- 基于jquery扩展漂亮的分页控件(ajax)
分页控件式大家在熟悉不过的控件,很多情况下都需要使用到分页控件来完成列表数据加载操作,在很多分页控件中有的编写麻烦,有的应用扩展比较复杂,有的分页控件样式比较丑陋,有的分页控件用户体验操作比较简单等等 ...
- asp.net分页控件库
AspNetPager分页控件 AspNetPager分页控件解决了分页中的很多问题,直接采用该控件进行分页处理,会将繁琐的分页工作变得简单化,下面是我如何使用AspNetPager控件进行分页处理的 ...
- 【NET】Winform分页控件初探
public partial class WinFormPager : UserControl { ; /// <summary> /// 当前页 /// </summary> ...
- 《ASP.NET1200例》ListView 控件与DataPager控件的结合<一>
分页 在前一部分开始时介绍的原 HTML 设计中内含分页和排序,所以根据规范完整实现该网格的任务尚未完成.我们先分页,然后再排序. ListView 控件中的分页通过引入另一个新控件 Data ...
- PCHMI工控组态开发视频教程
PCHMI是一款适合所有PLC工程师快速上手工控组态开发的控件 下面是视频教程链接 PCHMI工控组态 02-按钮的使用 PCHMI工控组态 03-数据显示器使用 PCHMI工控组态 04-标签控件的 ...
- 用C#开发ActiveX控件,并使用web调用
入职差不多两个月了,由学生慢慢向职场人做转变,也慢慢的积累知识,不断的更新自己.最近的一个项目里边,涉及到的一些问题,因为SDK提供的只是winform才能使用了,但是有需求咱们必须得完成啊,所以涉及 ...
随机推荐
- mysql版本导致的hibernate 方言问题
今天在看hibernate视频时,看到视频上人家的hibernate.cfg.xml配置文件在配置hibernate方言时,发现视频上是这样写的<property name="dial ...
- 算法笔记_219:泊松分酒(Java)
目录 1 问题描述 2 解决方案 1 问题描述 泊松是法国数学家.物理学家和力学家.他一生致力科学事业,成果颇多.有许多著名的公式定理以他的名字命名,比如概率论中著名的泊松分布. 有一次闲暇时,他 ...
- webapck 打包体积优化策略
一.概述 1.Tree-shaking 2.公共资源分离 3.图片压缩 二.Tree-shaking Tree-shaking:1个模块可能有多个方法,只要其中的某个方法使用到了,则整个文件都会被打到 ...
- 取自ACE中的bit操作宏(转)
# define ACE_BIT_ENABLED(WORD, BIT) (((WORD) & (BIT)) != ) # define ACE_BIT_DISABLED(WORD, BIT) ...
- 【Linux】处理数据文件
当存在大量数据的时候,通常很难处理这些信息及提取有用信息.Linux提供了一系列的命令行工具来处理这些数据. 1.排序数据 Linux:/usr/local/sbin # cat file2 1 0. ...
- python之获取微信服务器的ip地址
# -*- coding: cp936 -*- #PYTHON 27 #xiaodeng #获取微信服务器的ip地址 import urllib url='https://api.weixin.qq. ...
- python之函数用法endswith()
# -*- coding: utf-8 -*- #python 27 #xiaodeng #python之函数用法endswith() #http://www.runoob.com/python/at ...
- mybatis generator(MyBatis的逆向工程)
1创建数据表 如图所示:我的是在text数据库中创建了一个Student表,字段有id(int), name(varchar), age(int), score(int) 2创建项目 ...
- 转:Ogre的MaterialSystem分析
1. Mesh .SubMesh.SubEntity和Entity 所有的Mesh对象是由SubMesh构成的,每个SubMesh代表了Mesh对象的一部分,该部分只能使用一种Meterial.如果一 ...
- 转:高层游戏引擎——基于OGRE所实现的高层游戏引擎框架
高层游戏引擎——基于OGRE所实现的高层游戏引擎框架 这是意念自己的毕业论文,在一个具体的实践之中,意念主要负责的是物件和GUI之外的其他游戏系统.意念才学疏陋,望众位前辈不吝赐教.由于代码质量不高. ...