页面中数据的分页功能常常是令程序员比较头疼的一件事情,并非是技术原因,而是分页的繁琐(包括:风格统一、参数的维护……)。ASP.NET控件中的GridView和DataGrid等都直接支持分页,但这两中控件所擅长的是处理表格数据,而我们往往需要的显示风格要比表格丰富的多;以我往常经验,我比较喜欢Repeater,可一随心所欲的驾驭它来完成任何复杂的显示,但可惜的是它没有提供自动的分页功能。
\n
我们何不把这分页功能给封装起来呢?
\n
让我们来分析一下分页的封装到底要实现那些功能:
数据显示控件不应该关心“页”的问题,因为它的功能是显示数据,你只需要把它要显示的数据给它就行了;
你必须承认分页的独立性,它与任何显示控件物理上是隔离的,所以我们在设计该控件时不应该考虑任何数据显示控件;
分页控件需要维护一个“当前页”、“页大小”的上下文;
要确定分页控件的数据无关性(这里的“数据”指的是在数据显示控件中显示的数据),数据显示控件的数据源应该由系统的“业务层”提供,而业务层的数据提供服务所查询的具体数据有分页控件的“当前页”、“页大小”确定(如:GetData(int pageIndex,int pageSize););
分页控件必须能够维护当前页面的参数;
分页控件能够维护统一的风格(由用户指定显示样式,否则就显示默认样式)。
根据以上的分析,我们就可以来设计“分页控件”(SimplePaper)了,看看咱们的实现代码吧:
\n
首先实现的是SimplePaper维护的数据及属性,每个属性的描述这里就不再详述了
1 private string _class;
2 private int _pageSize = 10;
3 private int _numberCount = 10;
4 private int _virtualCount = 0;
5
6 private string _prevText = “上一页”;
7 private string _nextText = “下一页”;
8 private string _firstText = “第一页”;
9 private string _lastText = “最末页”;
10
11 /**//// <summary>
12 /// 获取或设置控件关联的样式类
13 /// </summary>
14 [Category("Behavior")]
15 [Description("Css的样式类名称")]
16 public string Class {
17 get {
18 return _class;
19 }
20 set {
21 _class = value;
22 }
23 }
24
25 /**//// <summary>
26 /// 获取或设置“上一页”在分页导航条中显示的文本,默认值“上一页”
27 /// </summary>
28 [Category("Behavior")]
29 [Description("上一页文本")]
30 public string PrevText {
31 get {
32 return _prevText;
33 }
34 set {
35 _prevText = value;
36 }
37 }
38
39 /**//// <summary>
40 /// 获取或设置“下一页”在分页导航条中显示的文本,默认值“下一页”
41 /// </summary>
42 [Category("Behavior")]
43 [Description("下一页文本")]
44 public string NextText {
45 get {
46 return _nextText;
47 }
48 set {
49 _nextText = value;
50 }
51 }
52
53 /**//// <summary>
54 /// 获取或设置“第一页”在分页导航条中显示的文本,默认值“第一页”
55 /// </summary>
56 [Category("Behavior")]
57 [Description("第一页文本")]
58 public string FirstText {
59 get {
60 return _firstText;
61 }
62 set {
63 _firstText = value;
64 }
65 }
66
67 /**//// <summary>
68 /// 获取或设置“最末页”在分页导航条中显示的文本,默认值“最末页”
69 /// </summary>
70 [Category("Behavior")]
71 [Description("最末页文本")]
72 public string LastText {
73 get {
74 return _lastText;
75 }
76 set {
77 _lastText = value;
78 }
79 }
80
81 /**//// <summary>
82 /// 获取或设置分页的大小,默认值10
83 /// </summary>
84 [Category("Behavior")]
85 [Description("页大小")]
86 public int PageSize {
87 get {
88 return _pageSize;
89 }
90 set {
91 _pageSize = value;
92 }
93 }
94
95 /**//// <summary>
96 /// 获取或设置分页导航条中显示的页码数量,默认10
97 /// </summary>
98 [Category("Behavior")]
99 [Description("分页中要显示的页码数量")]
100 public int NumberCount {
101 get {
102 return _numberCount;
103 }
104 set {
105 _numberCount = value;
106 }
107 }
108
109 /**//// <summary>
110 /// 获取或设置查询得到的总记录数
111 /// </summary>
112 [Browsable(false)]
113 public int VirtualCount {
114 get {
115 return _virtualCount;
116 }
117 set {
118 _virtualCount = value;
119 }
120 }
121
122 /**//// <summary>
123 /// 获取总页数
124 /// </summary>
125 [Browsable(false)]
126 public int PageCount {
127 get {
128 if (Context == null)
129 return 10;
130
131 int count = (VirtualCount – 1) / PageSize + 1;
132 if (count <= 0)
133 count = 1;
134
135 return count;
136 }
137 }
138
139 /**//// <summary>
140 /// 获取当前页码
141 /// </summary>
142 [Browsable(false)]
143 public int CurrentPage {
144 get {
145 if (Context == null)
146 return 1;
147
148 string tempPage = Page.Request.QueryString[KEY_PAGE];
149 int _currPage = 1;
150 if (!Int32.TryParse(tempPage, out _currPage)) {
151 _currPage = 1;
152 }
153 return _currPage;
154 }
155 }我们要维护当前页面的参数,这要费一点功夫了
1 private static string KEY_PAGE = “page”;
2 private static readonly Regex RX = new Regex(@”&page=\\d+”, RegexOptions.Compiled);
3
4 private string GetQueryFormat() {
5 // Prepare the query string
6 string query = “”;
7 if (Context != null) {
8 query = Page.Request.Url.Query.Replace(‘?’, ‘&’);
9 }
10
11 query = RX.Replace(query, String.Empty, -1);
12 query = “[<a href=\'?page={0}" + query + "\'>{1}</a>] ”;
13
14 return query;
15 }分页控件无非是在页面提供一个页码序列、上一页、下一页等超链接,我们只要让控件照样输出(Render)就可以了
\n
protected override void Render(HtmlTextWriter writer) {
string query = GetQueryFormat();
\n
// Prepare the necessary number
int page = CurrentPage;
int count = PageCount;
int nums = NumberCount-1;
int center = nums / 2;
int beginIndex = 1;
\n
// Calculate the first page number in the pagger bar
if (count > nums && page > center) {
beginIndex = page – center;
if ((count – beginIndex) <= nums)
beginIndex = count – nums;
}
\n
// Calculate the last page number in the pagger bar
int endIndex = beginIndex + nums;
if (endIndex > count)
endIndex = count;
\n
// Render the pagger bar
writer.AddAttribute(HtmlTextWriterAttribute.Id, ClientID);
if (!String.IsNullOrEmpty(_class)) {
writer.AddAttribute(HtmlTextWriterAttribute.Class, _class);
} else {
writer.AddStyleAttribute(HtmlTextWriterStyle.PaddingLeft, “18px”);
writer.AddStyleAttribute(HtmlTextWriterStyle.FontSize, “14px”);
writer.AddStyleAttribute(“word-spacing”, “4px”);
}
writer.RenderBeginTag(HtmlTextWriterTag.Div);
\n
writer.Write(String.Format(query, 1, FirstText));
writer.Write(String.Format(query, page>1?(page-1):1, PrevText));
for (int i = beginIndex; i <= endIndex; i++) {
if (page == i) {
writer.Write(i);
writer.Write(“ ”);
} else {
writer.Write(String.Format(query, i, i));
}
}
writer.Write(String.Format(query, page < count ? (page + 1) : page, NextText));
writer.Write(String.Format(query, count, LastText));
writer.Write(String.Format(“ {0} / {1}”, page, count));
\n
writer.RenderEndTag();
}
\n
好了,到现在,我们大功告成,整理起来试一下吧,很爽!!!点下载开始下载!
\n
来源:http://www.cnblogs.com/netEagle
\n