`
ihuashao
  • 浏览: 4563261 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

ASP.NET分页组件学与用——教学篇

阅读更多

ASP.NET分页组件学与用——教学篇<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

没有人会怀疑分页组件在WEB应用程序中的作用。数据库中的记录数成千上万甚至过亿,如果一股脑儿显示在一页显然毫不现实,这样的程序员也太小儿科了。所以,最好的办法就是分页显示,每页只显示数据库中的一部分记录,可以翻页,也可以输入一个页码翻到指定的页面,这种方式也是当前比较常见的用法。

本文的不同之处在于,我把分页的功能封装在组件中,一方面体现了面向对象的特点,另一方面也方便发布、共享和使用。事先声明,本文不再讲述组件创建的详细过程,如果有疑点请参考本BLOG其他相关文章(asp.net组件设计浅论,ASP.NET组件编程step by step)。

首先来看看该组件的外观:

<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" /><shapetype id="_x0000_t75" stroked="f" filled="f" path="m@4@5l@4@11@9@11@9@5xe" o:preferrelative="t" o:spt="75" coordsize="21600,21600"><font size="2"><stroke joinstyle="miter"></stroke><formulas><f eqn="if lineDrawn pixelLineWidth 0"></f><f eqn="sum @0 1 0"></f><f eqn="sum 0 0 @1"></f><f eqn="prod @2 1 2"></f><f eqn="prod @3 21600 pixelWidth"></f><f eqn="prod @3 21600 pixelHeight"></f><f eqn="sum @0 0 1"></f><f eqn="prod @6 1 2"></f><f eqn="prod @7 21600 pixelWidth"></f><f eqn="sum @8 21600 0"></f><f eqn="prod @7 21600 pixelHeight"></f><f eqn="sum @10 21600 0"></f></formulas><path o:extrusionok="f" o:connecttype="rect" gradientshapeok="t"></path><lock aspectratio="t" v:ext="edit"></lock></font></shapetype>

该组件最后运行显示在客户端其实是一个表格,表格被分成三段,第一段是与页和记录相关的信息;第二段是页导航,该导航显示一组带超链接的数字,通过点击数字可以转移到对应的页;第三段有两个HTML控件,用户可以输入数字转移到指定的页。从图中也可以看出,该组件的功能非常简单明了。

首先我们来关注第一部分。这一部分信息包括:当前页,总页数,每页显示的记录条数和总的记录条数。这些信息从组件外部传进来,所以我们定义对应的属性:

private int _count;//每页显示的记录条数

private int _currentPage;//当前页

private int _allCount;//所有记录条数

private int _showPages;//显示数字个数

我在注释_showPages这个属性的时候有点晦涩,所以需要简单的讲一下:该属性用来定义数字导航栏显示的数字个数,在上面的图中,定义显示10个数字,即从201——210,当然,根据需要,我们可以定义任意多个数字。

[DefaultValue(10),Category("Customer")]

public int Count

{

set

{

if(value <= 0)

_count = 1;

else

_count = value;

}

get

{

return _count;

}

}

[DefaultValue(1),Category("Customer")]

public int CurrentPage

{

set

{

if(value < 0)

_currentPage = 1;

else

_currentPage = value;

}

get

{

return _currentPage;

}

}

[DefaultValue(1),Category("Customer")]

public int AllCount

{

get

{

return _allCount;

}

set

{

if(_allCount < 0)

throw new Exception("记录总条数不能为负数");

else

_allCount = value;

}

}

[DefaultValue(1),Category("Customer")]

public int Pages//总页数

{

get

{

if(this._allCount % this._count > 0)

return ((int)this._allCount / this._count) + 1;

else

return ((int)this._allCount / this._count);

}

}

[DefaultValue(1),Category("Customer")]

public int ShowPages

{

set

{

if(value > 0)

_showPages = value;

else

_showPages = 9;

}

get

{

return _showPages;

}

}

在定义的属性中,有一个叫Pages的属性,该属性不需要从外面传值,而过计算出来的。他的值等于总记录条数除以每页显示的记录条数(具体请见代码)。

现在我们要把这些值显示出来,用下面的代码显示:

//分页条分三部分,leftInfo是最左边的部分,用来显示当前页/总页数,每页显示的记录条数

leftInfo = "页:" + this.CurrentPage.ToString() + "/" + this.Pages.ToString() + "&nbsp;&nbsp;" + "每页" + this.Count.ToString() + "条" + "&nbsp;&nbsp;共" + this.AllCount.ToString() + "条";

第二段比较复杂。组件的页面导航数字是连续的,所以,我定义了一个最小值和最大值:

int min;//要显示的页面导航数最小值

int max;//要显示的页面导航数最大值

设计时,需要考虑三种情况:

1:如果当前页除以ShowPages余数为0,也就是恰好可以整除的话,页面导航数字最小值和最大值分别是:

min最小值 = 当前页 + 1

max最大值 = 当前页 + 页面导航数字个数(ShowPages)

对应代码:

if(this.CurrentPage % this.ShowPages == 0) //如果恰好整除

{

min = this.CurrentPage + 1;

max = this.CurrentPage + this.ShowPages ;

}

2:如果当前页是导航数字最小值时,应该切换到前一组导航数字。此时,导航数字的最小值和最大值分别是:

min最小值 = (((int)当前页 / 页面导航数字个数ShowPages ) - 1) *页面导航数字个数ShowPages +1;

max最大值 = 当前页 1

对应代码如下:

else if(this.CurrentPage % this.ShowPages == 1 && this.CurrentPage > this.ShowPages )

{

min = (((int)this.CurrentPage / this.ShowPages ) - 1) * this.ShowPages +1;

max = this.CurrentPage - 1;

}

3:如果当前页是导航数字最大值时,应该切换到后一组导航数字。此时,导航数字的最小值和最大值分别是:

min最小值 = ((int)当前页 / 页面导航数字个数ShowPages) * 页面导航数字个数ShowPages + 1

max最大值 = (((int)当前页 / 页面导航数字个数ShowPages) +1) * 页面导航数字个数ShowPages

对应代码如下:

else

{

min = ((int)this.CurrentPage / this.ShowPages) * this.ShowPages + 1;

max = (((int)this.CurrentPage / this.ShowPages) +1) * this.ShowPages;

}

即然导航数字列表的最小值和最大值都计算出来了,所以我们通个做一个循环操作就可以生成该导航,当前页用斜体红色字体突出显示:

for(int i = min ; i <= max ; i++)

{

if(i <= this.Pages)//只有不大于最大页才显示

{

if(this.CurrentPage == i)//如果是当前页,用斜体和红色显示

{

numberStr = numberStr + "<a href=" + AbsUrl + "?currentPage=" + i.ToString() + ">" + "<I style='color:red'>" + i.ToString() + "</I>" +"</a>" + "\n";

}

else

{

numberStr = numberStr + "<a href=" + AbsUrl + "?currentPage=" + i.ToString() + ">" + i.ToString() +"</a>" + "\n";

}

}

}

大家应该看出来了,在导航列表的最前面和最后面一共还有四个图标,这几个图标并不是图片,而是7348四个数字的Wedding字体。这四个图标的代码如下:

//第一页,上一页,下一页,最后一页

string First,Previous,Next,Last;

First = AbsUrl + "?currentPage=1";

/////////

if(this.CurrentPage == 1)

Previous = AbsUrl + "?currentPage=1";

else

Previous = AbsUrl + "?currentPage=" + (this.CurrentPage - 1).ToString();

/////////

if(this.CurrentPage == this.Pages)

Next = AbsUrl + "?currentPage=" + this.Pages;

else

Next = AbsUrl + "?currentPage=" + (this.CurrentPage + 1).ToString();

/////////

Last = AbsUrl + "?currentPage=" + this.Pages;

接下来的代码就是生成要输出到客户端的HTML字符串:

centerInfo.AppendFormat("<font face='Webdings' style='font-size:14px'><a href={0}>7</a><a href={1}>3</a></font>{2}<font face='Webdings' style='font-size:14px'><a href={3}>4</a><a href={4}>8</a></font>",First,Previous,numberStr,Next,Last);

StringBuilder sb = new StringBuilder();//HTML字符串

sb.AppendFormat("<table style = 'font-size:12px' border='0' cellpadding='0' cellspacing='0' width='100%'> \n " +

"<tr>\n" +

"<td width='25%' align='left'>{0}</td>\n" +

"<td width='61%' align='right'>{1}</td>\n" +

"<td width='14%' align='right'><input type='text' name='T1' size='4' style='border-bottom:solid 1pt gray;border-top :solid 1pt gray; border-left:solid 1pt gray;border-right:solid 1pt gray;'> \n <input type='button' name='B1' size='6' value=go style='border-bottom:solid 1pt gray;border-top :solid 1pt gray; border-left:solid 1pt gray;border-right:solid 1pt gray;' onclick='go(T1,{2})'></td>\n" +

"</tr>\n" +

"</table>",leftInfo,

centerInfo.ToString(),

this.Pages);

真正输出,重写protected override void Render(HtmlTextWriter writer)方法,输出代码如下:writer.Write(sb.ToString());

很辛苦,不过辛苦还要继续。呵!^_^

最后要完成的是第三段了,这一段我们用JavaScript脚本完成。用户输入数据到文本框时,先检测是否符合要求,不能是非数字,也不能超过最大页面范围。如果符合要求,则将浏览器的地址栏改成对应的URL地址即可。

脚本如下:

<script language="javascript">

function go(ctrl,max)

{

if(ctrl.value >= 1 && ctrl.value <= max)

{

var url;

var index;

url = location.href;

index = url.indexOf('?');

if(index == -1)

{

}

else

{

url = url.substring(0,index);

}

location.href = url + "?currentPage=" + ctrl.value;

}

else

{

alert("您输入的页码必须是符合页面要求的数字,最大值是" + max);

return false;

}

}

</script>

参数说明:ctrl是文本框,max是输入的最大值,也就是总页数。

重写OnPreRender()方法,将该段脚本输入到浏览器:

protected override void OnPreRender(EventArgs e)

{

base.OnPreRender (e);

if(!Page.IsClientScriptBlockRegistered("WEREW-332DFAF-FDAFDSFDSAFD"))

{ Page.RegisterClientScriptBlock("WEREW-332DFAF-FDAFDSFDSAFD",SCRIPTSTRING);

}

}

分享到:
评论

相关推荐

    ASP.NET开发伴侣--分页组件

    二、产品特点1、ASP.Net开发伴侣——分页组件,使用简单,功能强大2、支持Sql聚合函数(sum,count,avg等)、case函数;3、支持分组分页功能,可以完成Group by、Order By 等复杂的SQL语句所实现的强大功能;4、支持...

    asp.net知识库

    深入剖析ASP.NET组件设计]一书第三章关于ASP.NET运行原理讲述的补白 asp.net 运行机制初探(httpModule加载) 利用反射来查看对象中的私有变量 关于反射中创建类型实例的两种方法 ASP.Net应用程序的多进程模型 NET委托...

    亮剑.NET深入体验与实战精要2

    1.6.1 如何创建ASP.NET项目 58 1.6.2 如何创建Windows项目 61 1.6.3 Visual Studio.NET 2008 操作与使用技巧 61 1.6.4 常见开发调试技巧 66 1.6.5 错误异常处理方法 70 本章常见技术面试题 76 常见面试技巧之面试...

    亮剑.NET深入体验与实战精要3

    1.6.1 如何创建ASP.NET项目 58 1.6.2 如何创建Windows项目 61 1.6.3 Visual Studio.NET 2008 操作与使用技巧 61 1.6.4 常见开发调试技巧 66 1.6.5 错误异常处理方法 70 本章常见技术面试题 76 常见面试技巧之面试...

    ASP.NET开发实战1200例(第Ⅰ卷)第十二章

    实例312 用WebBrowser组件的execWB方法 进行打印 491 实例313 利用JavaScript获取焦点并且打印 框架中内容 492 实例314 智能放大或者缩小图片后进行打印 494 实例315 清空或恢复打印页面中的页眉和页脚 495 实例316...

    仿世纪佳缘婚介交友系统5.3 ASP+SQL

    2、组件要求:Jmail邮件组件、aspjpeg水印组件、上传组件(aspupload组件)、FSO读写权限(IIS_IUSRS,IUSR帐号读写)、ADODB.Stream组件。一般的虚拟主机都有这些组件,如果是本地调试必须先检查一下IIS的设置环境...

    JAVA上百实例源码以及开源项目源代码

    得到RSA密钥对,产生Signature对象,对用私钥对信息(info)签名,用指定算法产生签名对象,用私钥初始化签名对象,将待签名的数据传送给签名对象(须在初始化之后),用公钥验证签名结果,使用公钥初始化签名对象,用于...

    Roclog 个人博客系统 v5.0.23.0开源

    1.取消外部压缩组件,使用Winrar压缩(协力解决中,如发现有不正常状况请停止使用并采用人工方式操作) 2.后台模板文件编辑识别*.js及其它文本文件 3.相关文章函数重新设计 4.密码文章的入口方式变更 5.搜索方式和...

    基于J2EE框架的个人博客系统项目毕业设计论文(源码和论文)

    而JSP的组件是用Java开发的,可以直接使用; 4、一次编写,处处运行:作为JAVA开发平台的一部分,JSP具有JAVA的所有优点,包括Write once , Run everywhere. 3.2. 数据库的选择 3.2.1. Web应用程序开发环境—SQL...

    JAVA上百实例源码以及开源项目

    得到RSA密钥对,产生Signature对象,对用私钥对信息(info)签名,用指定算法产生签名对象,用私钥初始化签名对象,将待签名的数据传送给签名对象(须在初始化之后),用公钥验证签名结果,使用公钥初始化签名对象,用于...

Global site tag (gtag.js) - Google Analytics