您的位置:首页 > 编程语言 > ASP

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

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

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

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



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

首先我们来关注第一部分。这一部分信息包括:当前页,总页数,每页显示的记录条数和总的记录条数。这些信息从组件外部传进来,所以我们定义对应的属性:
[align=left] private int _count;//每页显示的记录条数[/align]
[align=left] private int _currentPage;//当前页[/align]
[align=left] private int _allCount;//所有记录条数[/align]
private int _showPages;//显示数字个数
我在注释_showPages这个属性的时候有点晦涩,所以需要简单的讲一下:该属性用来定义数字导航栏显示的数字个数,在上面的图中,定义显示10个数字,即从201——210,当然,根据需要,我们可以定义任意多个数字。

[align=left][DefaultValue(10),Category("Customer")][/align]
[align=left] public int Count[/align]
[align=left] {[/align]
[align=left] set[/align]
[align=left] {[/align]
[align=left] if(value <= 0)[/align]
[align=left] _count = 1;[/align]
[align=left] else[/align]
[align=left] _count = value;[/align]
[align=left] }[/align]
[align=left] get[/align]
[align=left] {[/align]
[align=left] return _count;[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] [DefaultValue(1),Category("Customer")][/align]
[align=left] public int CurrentPage[/align]
[align=left] {[/align]
[align=left] set[/align]
[align=left] {[/align]
[align=left] if(value < 0)[/align]
[align=left] _currentPage = 1;[/align]
[align=left] else[/align]
[align=left] _currentPage = value;[/align]
[align=left] }[/align]
[align=left] get[/align]
[align=left] {[/align]
[align=left] return _currentPage;[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] [DefaultValue(1),Category("Customer")][/align]
[align=left] public int AllCount[/align]
[align=left] {[/align]
[align=left] get[/align]
[align=left] {[/align]
[align=left] return _allCount;[/align]
[align=left] }[/align]
[align=left] set[/align]
[align=left] {[/align]
[align=left] if(_allCount < 0)[/align]
[align=left] throw new Exception("记录总条数不能为负数");[/align]
[align=left] else[/align]
[align=left] _allCount = value;[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] [DefaultValue(1),Category("Customer")][/align]
[align=left] public int Pages//总页数[/align]
[align=left] {[/align]
[align=left] get[/align]
[align=left] {[/align]
[align=left] if(this._allCount % this._count > 0)[/align]
[align=left] return ((int)this._allCount / this._count) + 1;[/align]
[align=left] else[/align]
[align=left] return ((int)this._allCount / this._count);[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] [DefaultValue(1),Category("Customer")][/align]
[align=left] public int ShowPages[/align]
[align=left] {[/align]
[align=left] set[/align]
[align=left] {[/align]
[align=left] if(value > 0)[/align]
[align=left] _showPages = value;[/align]
[align=left] else[/align]
[align=left] _showPages = 9;[/align]
[align=left] }[/align]
[align=left] get[/align]
[align=left] {[/align]
[align=left] return _showPages;[/align]
[align=left] }[/align]
}

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

现在我们要把这些值显示出来,用下面的代码显示:
//分页条分三部分,leftInfo是最左边的部分,用来显示当前页/总页数,每页显示的记录条数
leftInfo = "页:" + this.CurrentPage.ToString() + "/" + this.Pages.ToString() + "  " + "每页" + this.Count.ToString() + "条" + "  共" + this.AllCount.ToString() + "条";

第二段比较复杂。组件的页面导航数字是连续的,所以,我定义了一个最小值和最大值:
[align=left]int min;//要显示的页面导航数最小值[/align]
int max;//要显示的页面导航数最大值

设计时,需要考虑三种情况:
1:如果当前页除以ShowPages余数为0,也就是恰好可以整除的话,页面导航数字最小值和最大值分别是:
min最小值 = 当前页 + 1
max最大值 = 当前页 + 页面导航数字个数(ShowPages)
对应代码:
[align=left]if(this.CurrentPage % this.ShowPages == 0) //如果恰好整除[/align]
[align=left] {[/align]
[align=left] min = this.CurrentPage + 1;[/align]
[align=left] max = this.CurrentPage + this.ShowPages ;[/align]
}
2:如果当前页是导航数字最小值时,应该切换到前一组导航数字。此时,导航数字的最小值和最大值分别是:
min最小值 = (((int)当前页 / 页面导航数字个数ShowPages ) - 1) *页面导航数字个数ShowPages +1;
max最大值 = 当前页 –1
对应代码如下:
[align=left]else if(this.CurrentPage % this.ShowPages == 1 && this.CurrentPage > this.ShowPages )[/align]
[align=left] {[/align]
[align=left] min = (((int)this.CurrentPage / this.ShowPages ) - 1) * this.ShowPages +1;[/align]
[align=left] max = this.CurrentPage - 1;[/align]
}

3:如果当前页是导航数字最大值时,应该切换到后一组导航数字。此时,导航数字的最小值和最大值分别是:
min最小值 = ((int)当前页 / 页面导航数字个数ShowPages) * 页面导航数字个数ShowPages + 1
max最大值 = (((int)当前页 / 页面导航数字个数ShowPages) +1) * 页面导航数字个数ShowPages
对应代码如下:
[align=left]else[/align]
[align=left] {[/align]
[align=left] min = ((int)this.CurrentPage / this.ShowPages) * this.ShowPages + 1;[/align]
[align=left] max = (((int)this.CurrentPage / this.ShowPages) +1) * this.ShowPages;[/align]
}

即然导航数字列表的最小值和最大值都计算出来了,所以我们通个做一个循环操作就可以生成该导航,当前页用斜体和红色字体突出显示:
[align=left]for(int i = min ; i <= max ; i++)[/align]
[align=left]{ [/align]
[align=left] if(i <= this.Pages)//只有不大于最大页才显示[/align]
[align=left] {[/align]
[align=left] if(this.CurrentPage == i)//如果是当前页,用斜体和红色显示[/align]
[align=left] {[/align]
[align=left] numberStr = numberStr + "<a href=" + AbsUrl + "?currentPage=" + i.ToString() + ">" + "<I style='color:red'>" + i.ToString() + "</I>" +"</a>" + "/n";[/align]
[align=left] }[/align]
[align=left] else[/align]
[align=left] {[/align]
[align=left] numberStr = numberStr + "<a href=" + AbsUrl + "?currentPage=" + i.ToString() + ">" + i.ToString() +"</a>" + "/n";[/align]
[align=left] }[/align]
[align=left] }[/align]
}
大家应该看出来了,在导航列表的最前面和最后面一共还有四个图标,这几个图标并不是图片,而是7348四个数字的Wedding字体。这四个图标的代码如下:
[align=left]//第一页,上一页,下一页,最后一页[/align]
[align=left]string First,Previous,Next,Last;[/align]
[align=left]First = AbsUrl + "?currentPage=1";[/align]
[align=left]/////////[/align]
[align=left]if(this.CurrentPage == 1)[/align]
[align=left] Previous = AbsUrl + "?currentPage=1";[/align]
[align=left]else[/align]
[align=left] Previous = AbsUrl + "?currentPage=" + (this.CurrentPage - 1).ToString();[/align]
[align=left]/////////[/align]
[align=left]if(this.CurrentPage == this.Pages)[/align]
[align=left] Next = AbsUrl + "?currentPage=" + this.Pages;[/align]
[align=left]else[/align]
[align=left] Next = AbsUrl + "?currentPage=" + (this.CurrentPage + 1).ToString();[/align]
[align=left]/////////[/align]
Last = AbsUrl + "?currentPage=" + this.Pages;

接下来的代码就是生成要输出到客户端的HTML字符串:
[align=left]centerInfo.AppendFormat("<font style='font-size:14px'><a href={0}>7</a><a href={1}>3</a></font>{2}<font style='font-size:14px'><a href={3}>4</a><a href={4}>8</a></font>",First,Previous,numberStr,Next,Last);[/align]
[align=left] [/align]
[align=left]StringBuilder sb = new StringBuilder();//HTML字符串[/align]
[align=left]sb.AppendFormat("<table style = 'font-size:12px' border='0' cellpadding='0' cellspacing='0' width='100%'> /n " +[/align]
[align=left] "<tr>/n" +[/align]
[align=left] "<td width='25%' align='left'>{0}</td>/n" +[/align]
[align=left] "<td width='61%' align='right'>{1}</td>/n" +[/align]
[align=left] "<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" +[/align]
[align=left] "</tr>/n" +[/align]
[align=left] "</table>",leftInfo,[/align]
[align=left] centerInfo.ToString(),[/align]
this.Pages);

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

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

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

脚本如下:
[align=left] <script language="javascript">[/align]
[align=left] function go(ctrl,max)[/align]
[align=left] {[/align]
[align=left] if(ctrl.value >= 1 && ctrl.value <= max)[/align]
[align=left] {[/align]
[align=left] var url;[/align]
[align=left] var index;[/align]
[align=left] url = location.href;[/align]
[align=left] index = url.indexOf('?');[/align]
[align=left] if(index == -1)[/align]
[align=left] {[/align]
[align=left] }[/align]
[align=left] else[/align]
[align=left] {[/align]
[align=left] url = url.substring(0,index);[/align]
[align=left] }[/align]
[align=left] location.href = url + "?currentPage=" + ctrl.value;[/align]
[align=left] [/align]
[align=left] }[/align]
[align=left] else[/align]
[align=left] {[/align]
[align=left] alert("您输入的页码必须是符合页面要求的数字,最大值是:" + max);[/align]
[align=left] return false;[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left]</script>[/align]
参数说明:ctrl是文本框,max是输入的最大值,也就是总页数。

重写OnPreRender()方法,将该段脚本输入到浏览器:
[align=left]protected override void OnPreRender(EventArgs e)[/align]
[align=left]{[/align]
[align=left] base.OnPreRender (e);[/align]
[align=left] if(!Page.IsClientScriptBlockRegistered("WEREW-332DFAF-FDAFDSFDSAFD"))[/align]
[align=left] { Page.RegisterClientScriptBlock("WEREW-332DFAF-FDAFDSFDSAFD",SCRIPTSTRING);[/align]
[align=left] }[/align]
}
终于讲完了,听懂了吗?有词不达意的地方请多原谅。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: