1
using System;
2
using System.IO;
3
using System.Drawing;
4
using System.Data;
5
using System.Data.SqlClient;
6
using System.Web.UI;
7
using System.Web.UI.WebControls;
8
using System.ComponentModel;
9
using System.Configuration;
10
11
namespace DevCenter
12

{
13
枚举 缓存模式#region 枚举 缓存模式
14
public enum PagingMode
15
{
16
//缓存
17
Cached,
18
//不缓存
19
NonCached
20
}
21
#endregion
22
23
枚举 导航条样式#region 枚举 导航条样式
24
public enum PagerStyle
25
{
26
Character,
27
NextPrev,
28
NumericPages
29
}
30
#endregion
31
32
枚举 排序模式#region 枚举 排序模式
33
public enum SortMode
34
{
35
ASC,
36
DESC
37
}
38
#endregion
39
40
类 记录统计#region 类 记录统计
41
public class VirtualRecordCount
42
{
43
public int RecordCount;
44
public int PageCount;
45
//最后一页的记录数
46
public int RecordsInLastPage;
47
}
48
#endregion
49
50
类 页面改变事件参数#region 类 页面改变事件参数
51
public class PageChangedEventArgs : EventArgs
52
{
53
public int OldPageIndex;
54
public int NewPageIndex;
55
}
56
#endregion
57
58
SqlPager分页控件#region SqlPager分页控件
59
60
[DefaultProperty("SelectCommand")]
61
[DefaultEvent("PageIndexChanged")]
62
[ToolboxData("<{0}:SqlPager runat=\"server\" />")]
63
public class SqlPager : WebControl, INamingContainer
64
{
65
私有成员#region 私有成员
66
// ***********************************************************************
67
// 私有成员
68
69
//数据源
70
private PagedDataSource _dataSource;
71
//数据容器
72
private Control _controlToPaginate;
73
private string CacheKeyName
74
{
75
get
{return Page.Request.FilePath + "_" + UniqueID + "_Data";}
76
}
77
//导航条页面信息显示
78
private string CurrentPageText = "当前第<font color={0}>{1}</font>页 共分<font color={0}>{2}</font>页 总计<font color={0}>{3}</font>条 每页<font color={0}>{4}</font>条";
79
//导航条无记录显示
80
private string NoPageSelectedText = "没有记录!";
81
//格式化sql查询语句
82
private string QueryPageCommandText = "SELECT * FROM " +
83
"(SELECT TOP {0} * FROM " +
84
"(SELECT TOP {1} * FROM ({2}) AS t0 ORDER BY {3} {4}) AS t1 " +
85
"ORDER BY {3} {5}) AS t2 " +
86
"ORDER BY {3} {4}";
87
//格式化sql记录统计语句
88
private string QueryCountCommandText = "SELECT COUNT(*) FROM ({0}) AS t0";
89
// ***********************************************************************
90
#endregion
91
92
构造器#region 构造器
93
// ***********************************************************************
94
// 构造器
95
public SqlPager() : base()
96
{
97
_dataSource = null;
98
_controlToPaginate = null;
99
100
Font.Name = "verdana";
101
Font.Size = FontUnit.Point(9);
102
BackColor = Color.Gainsboro;
103
ForeColor = Color.Black;
104
IndexColor = Color.Black;
105
BorderStyle = BorderStyle.Outset;
106
BorderWidth = Unit.Parse("1px");
107
PagingMode = PagingMode.NonCached;
108
PagerStyle = PagerStyle.Character;
109
CurrentPageIndex = 0;
110
SelectCommand = "";
111
ConnectionString = "";
112
ItemsPerPage = 15;
113
TotalPages = -1;
114
CacheDuration = 60;
115
SortMode = SortMode.DESC;
116
ConnectionString = ConfigurationSettings.AppSettings["CONN_STR"];
117
}
118
// ***********************************************************************
119
#endregion
120
121
公共程序接口#region 公共程序接口
122
123
124
方法 清空缓存#region 方法 清空缓存
125
/**//**//**//// <summary>
126
/// 方法 清空缓存
127
/// </summary>
128
public void ClearCache()
129
{
130
if (PagingMode == PagingMode.Cached)
131
Page.Cache.Remove(CacheKeyName);
132
}
133
#endregion
134
135
136
事件 页面索引改变#region 事件 页面索引改变
137
// ***********************************************************************
138
/**//**//**//// <summary>
139
/// 事件 页面索引改变
140
/// 当跳转到新页面时发生
141
/// </summary>
142
public delegate void PageChangedEventHandler(object sender, PageChangedEventArgs e);
143
public event PageChangedEventHandler PageIndexChanged;
144
protected virtual void OnPageIndexChanged(PageChangedEventArgs e)
145
{
146
if (PageIndexChanged != null)
147
PageIndexChanged(this, e);
148
}
149
// ***********************************************************************
150
#endregion
151
152
153
属性 缓存过期时间#region 属性 缓存过期时间
154
// ***********************************************************************
155
// 属性 缓存过期时间
156
[Description("取得或设置数据在缓存中保存多少秒")]
157
public int CacheDuration
158
{
159
get
{return Convert.ToInt32(ViewState["CacheDuration"]);}
160
set
{ViewState["CacheDuration"] = value;}
161
}
162
// ***********************************************************************
163
#endregion
164
165
属性 缓存模式#region 属性 缓存模式
166
// ***********************************************************************
167
// 属性 缓存模式
168
[Description("指定数据是否需要在页面上缓存")]
169
public PagingMode PagingMode
170
{
171
get
{return (PagingMode) ViewState["PagingMode"];}
172
set
{ViewState["PagingMode"] = value;}
173
}
174
// ***********************************************************************
175
#endregion
176
177
属性 导航条样式#region 属性 导航条样式
178
// ***********************************************************************
179
// 属性 导航条样式
180
[Description("指定导航条样式")]
181
public PagerStyle PagerStyle
182
{
183
get
{return (PagerStyle) ViewState["PagerStyle"];}
184
set
{ViewState["PagerStyle"] = value;}
185
}
186
// ***********************************************************************
187
#endregion
188
189
属性 索引值颜色#region 属性 索引值颜色
190
// ***********************************************************************
191
// 属性 索引值颜色
192
[Description("指定索引值颜色")]
193
public Color IndexColor
194
{
195
get
{return (Color) ViewState["IndexColor"];}
196
set
{ViewState["IndexColor"] = value;}
197
}
198
// ***********************************************************************
199
#endregion
200
201
属性 数据容器#region 属性 数据容器
202
// ***********************************************************************
203
// 属性 数据容器
204
[Description("取得设置数据容器的名字")]
205
public string ControlToPaginate
206
{
207
get
{return Convert.ToString(ViewState["ControlToPaginate"]);}
208
set
{ViewState["ControlToPaginate"] = value;}
209
}
210
// ***********************************************************************
211
#endregion
212
213
属性 每页记录数#region 属性 每页记录数
214
// ***********************************************************************
215
// 属性 每页记录数
216
[Description("取得设置每页显示的记录数")]
217
public int ItemsPerPage
218
{
219
get
{return Convert.ToInt32(ViewState["ItemsPerPage"]);}
220
set
{ViewState["ItemsPerPage"] = value;}
221
}
222
// ***********************************************************************
223
#endregion
224
225
属性 当前页索引#region 属性 当前页索引
226
// ***********************************************************************
227
// 属性 当前页索引
228
[Description("取得设置当前页面索引")]
229
public int CurrentPageIndex
230
{
231
get
{return Convert.ToInt32(ViewState["CurrentPageIndex"]);}
232
set
{ViewState["CurrentPageIndex"] = value;}
233
}
234
// ***********************************************************************
235
#endregion
236
237
属性 连接字符串#region 属性 连接字符串
238
// ***********************************************************************
239
// 属性 连接字符串
240
[Description("取得设置数据库连接字符串")]
241
public string ConnectionString
242
{
243
get
{return Convert.ToString(ViewState["ConnectionString"]);}
244
set
{ViewState["ConnectionString"] = value;}
245
}
246
// ***********************************************************************
247
#endregion
248
249
属性 查询语句#region 属性 查询语句
250
// ***********************************************************************
251
// 属性 查询语句
252
[Description("取得设置数据库查询语句")]
253
public string SelectCommand
254
{
255
get
{return Convert.ToString(ViewState["SelectCommand"]);}
256
set
{ViewState["SelectCommand"] = value;}
257
}
258
// ***********************************************************************
259
#endregion
260
261
属性 排序字段#region 属性 排序字段
262
// ***********************************************************************
263
// 属性 排序字段
264
[Description("取得设置排序字段,仅在无缓存的模式下可用")]
265
public string SortField
266
{
267
get
{return Convert.ToString(ViewState["SortKeyField"]);}
268
set
{ViewState["SortKeyField"] = value;}
269
}
270
// ***********************************************************************
271
#endregion
272
273
属性 总页数#region 属性 总页数
274
// ***********************************************************************
275
// 属性 总页数
276
// 取得显示页面的总数
277
[Browsable(false)]
278
public int PageCount
279
{
280
get
{return TotalPages;}
281
}
282
// ***********************************************************************
283
#endregion
284
285
属性 总页数#region 属性 总页数
286
// ***********************************************************************
287
// 属性 总页数
288
// 取得设置显示页面的总数
289
protected int TotalPages
290
{
291
get
{return Convert.ToInt32(ViewState["TotalPages"]);}
292
set
{ViewState["TotalPages"] = value;}
293
}
294
// ***********************************************************************
295
#endregion
296
297
属性 总记录数#region 属性 总记录数
298
// ***********************************************************************
299
// 属性 总记录数
300
// 取得设置总记录数
301
protected int TotalRecords
302
{
303
get
{return Convert.ToInt32(ViewState["TotalRecords"]);}
304
set
{ViewState["TotalRecords"] = value;}
305
}
306
// ***********************************************************************
307
#endregion
308
309
属性 排序模式#region 属性 排序模式
310
// ***********************************************************************
311
// 属性 排序模式
312
[Description("取得设置排序模式")]
313
public SortMode SortMode
314
{
315
get
{return (SortMode) ViewState["SortMode"];}
316
set
{ViewState["SortMode"] = value;}
317
}
318
// ***********************************************************************
319
#endregion
320
321
322
方法 重载 数据绑定#region 方法 重载 数据绑定
323
// ***********************************************************************
324
// 方法 重载数据绑定
325
/**//**//**//// <summary>
326
/// 取得,填充数据
327
/// </summary>
328
public override void DataBind()
329
{
330
// 触发数据绑定事件
331
base.DataBind();
332
333
// 控件必须在数据绑定后重新创建
334
ChildControlsCreated = false;
335
336
// 确定数据容器存在并且为列表控件(list control)
337
if (ControlToPaginate == "")
338
return;
339
_controlToPaginate = Page.FindControl(ControlToPaginate);
340
if (_controlToPaginate == null)
341
return;
342
if (!(_controlToPaginate is BaseDataList || _controlToPaginate is ListControl))
343
return;
344
345
// 确定数据库连接字符串有效且查询命令已指定
346
if (ConnectionString == "" || SelectCommand == "")
347
return;
348
349
// 取得数据
350
if (PagingMode == PagingMode.Cached)
351
FetchAllData();
352
else
353
{
354
//if (SortField == "")
355
// return;
356
FetchPageData();
357
}
358
359
// Bind data to the buddy control
360
// 绑定数据到数据容器
361
BaseDataList baseDataListControl = null;
362
ListControl listControl = null;
363
if (_controlToPaginate is BaseDataList)
364
{
365
baseDataListControl = (BaseDataList) _controlToPaginate;
366
baseDataListControl.DataSource = _dataSource;
367
baseDataListControl.DataBind();
368
return;
369
}
370
if (_controlToPaginate is ListControl)
371
{
372
listControl = (ListControl) _controlToPaginate;
373
listControl.Items.Clear();
374
listControl.DataSource = _dataSource;
375
listControl.DataBind();
376
return;
377
}
378
}
379
// ***********************************************************************
380
#endregion
381
382
方法 重载 传递数据#region 方法 重载 传递数据
383
// ***********************************************************************
384
// 方法 重载 传递数据
385
// 把数据内容传递到客户端
386
protected override void Render(HtmlTextWriter output)
387
{
388
// If in design-mode ensure that child controls have been created.
389
// Child controls are not created at this time in design-mode because
390
// there's no pre-render stage. Do so for composite controls like this
391
if (Site != null && Site.DesignMode)
392
CreateChildControls();
393
394
base.Render(output);
395
}
396
// ***********************************************************************
397
#endregion
398
399
方法 重载 创建子控件#region 方法 重载 创建子控件
400
// ***********************************************************************
401
// 方法 重载 创建子控件
402
// Outputs the HTML markup for the control
403
protected override void CreateChildControls()
404
{
405
Controls.Clear();
406
ClearChildViewState();
407
408
BuildControlHierarchy();
409
}
410
// ***********************************************************************
411
#endregion
412
413
414
#endregion
415
416
私有方法#region 私有方法
417
418
方法 创建导航条#region 方法 创建导航条
419
// ***********************************************************************
420
// 方法 创建导航条
421
private void BuildControlHierarchy()
422
{
423
// 导航条表格,1行2列
424
Table t = new Table();
425
t.Font.Name = Font.Name;
426
t.Font.Size = Font.Size;
427
t.BorderStyle = BorderStyle;
428
t.BorderWidth = BorderWidth;
429
t.BorderColor = BorderColor;
430
t.Width = Width;
431
t.Height = Height;
432
t.BackColor = BackColor;
433
t.ForeColor = ForeColor;
434
435
// 表格行
436
TableRow row = new TableRow();
437
t.Rows.Add(row);
438
439
// 页面索引单元格
440
TableCell cellPageDesc = new TableCell();
441
cellPageDesc.HorizontalAlign = HorizontalAlign.Right;
442
BuildCurrentPage(cellPageDesc);
443
row.Cells.Add(cellPageDesc);
444
445
// 导航按钮单元格
446
TableCell cellNavBar = new TableCell();
447
448
switch(PagerStyle)
449
{
450
//字符导航条
451
case PagerStyle.Character:
452
BuildCharacterUI(cellNavBar);
453
break;
454
case PagerStyle.NextPrev:
455
BuildNextPrevUI(cellNavBar);
456
break;
457
case PagerStyle.NumericPages:
458
BuildNumericPagesUI(cellNavBar);
459
break;
460
default:
461
break;
462
}
463
464
row.Cells.Add(cellNavBar);
465
466
TableCell cellTip = new TableCell();
467
cellTip.Text = "跳转到";
468
row.Cells.Add(cellTip);
469
470
//跳转到指定页输入框和按钮
471
TableCell cellGotoPage = new TableCell();
472
BuildGotoPage(cellGotoPage);
473
row.Cells.Add(cellGotoPage);
474
475
// 把表格加入到控件树
476
Controls.Add(t);
477
}
478
// ***********************************************************************
479
#endregion
480
481
建立字符导航栏#region 建立字符导航栏
482
/**//**//**//// <summary>
483
/// 建立字符导航栏
484
/// </summary>
485
/// <param name="cell"></param>
486
private void BuildCharacterUI(TableCell cell)
487
{
488
bool isValidPage = (CurrentPageIndex >=0 && CurrentPageIndex <= TotalPages-1);
489
bool canMoveBack = (CurrentPageIndex>0);
490
bool canMoveForward = (CurrentPageIndex<TotalPages-1);
491
492
//定义首页按钮式样
493
LinkButton first = new LinkButton();
494
first.ID = "First";
495
first.CausesValidation = false;
496
first.Click += new EventHandler(first_Click);
497
first.ToolTip = "首页";
498
first.Text = "首页";
499
first.Enabled = isValidPage && canMoveBack;
500
cell.Controls.Add(first);
501
502
//加空格
503
cell.Controls.Add(new LiteralControl(" "));
504
505
//定义前页按钮式样
506
LinkButton prev = new LinkButton();
507
prev.ID = "Prev";
508
prev.CausesValidation = false;
509
prev.Click += new EventHandler(prev_Click);
510
prev.ToolTip = "前页";
511
prev.Text = "前页";
512
prev.Enabled = isValidPage && canMoveBack;
513
cell.Controls.Add(prev);
514
515
//加空格
516
cell.Controls.Add(new LiteralControl(" "));
517
518
//定义后页按钮式样
519
LinkButton next = new LinkButton();
520
next.ID = "Next";
521
next.CausesValidation = false;
522
next.Click += new EventHandler(next_Click);
523
next.ToolTip = "后页";
524
next.Text = "后页";
525
next.Enabled = isValidPage && canMoveForward;
526
cell.Controls.Add(next);
527
528
//加空格
529
cell.Controls.Add(new LiteralControl(" "));
530
531
//定义尾页按钮式样
532
LinkButton last = new LinkButton();
533
last.ID = "Last";
534
last.CausesValidation = false;
535
last.Click += new EventHandler(last_Click);
536
last.ToolTip = "尾页";
537
last.Text = "尾页";
538
last.Enabled = isValidPage && canMoveForward;
539
cell.Controls.Add(last);
540
}
541
// ***********************************************************************
542
#endregion
543
544
BuildNextPrevUI#region BuildNextPrevUI
545
// ***********************************************************************
546
// PRIVATE BuildNextPrevUI
547
// Generates the HTML markup for the Next/Prev navigation bar
548
private void BuildNextPrevUI(TableCell cell)
549
{
550
bool isValidPage = (CurrentPageIndex >=0 && CurrentPageIndex <= TotalPages-1);
551
bool canMoveBack = (CurrentPageIndex>0);
552
bool canMoveForward = (CurrentPageIndex<TotalPages-1);
553
554
// Render the << button
555
LinkButton first = new LinkButton();
556
first.ID = "First";
557
first.Click += new EventHandler(first_Click);
558
first.Font.Name = "webdings";
559
first.Font.Size = FontUnit.Medium;
560
first.ForeColor = ForeColor;
561
first.ToolTip = "First page";
562
first.Text = "7";
563
first.Enabled = isValidPage && canMoveBack;
564
cell.Controls.Add(first);
565
566
// Add a separator
567
cell.Controls.Add(new LiteralControl(" "));
568
569
// Render the < button
570
LinkButton prev = new LinkButton();
571
prev.ID = "Prev";
572
prev.Click += new EventHandler(prev_Click);
573
prev.Font.Name = "webdings";
574
prev.Font.Size = FontUnit.Medium;
575
prev.ForeColor = ForeColor;
576
prev.ToolTip = "Previous page";
577
prev.Text = "3";
578
prev.Enabled = isValidPage && canMoveBack;
579
cell.Controls.Add(prev);
580
581
// Add a separator
582
cell.Controls.Add(new LiteralControl(" "));
583
584
// Render the > button
585
LinkButton next = new LinkButton();
586
next.ID = "Next";
587
next.Click += new EventHandler(next_Click);
588
next.Font.Name = "webdings";
589
next.Font.Size = FontUnit.Medium;
590
next.ForeColor = ForeColor;
591
next.ToolTip = "Next page";
592
next.Text = "4";
593
next.Enabled = isValidPage && canMoveForward;
594
cell.Controls.Add(next);
595
596
// Add a separator
597
cell.Controls.Add(new LiteralControl(" "));
598
599
// Render the >> button
600
LinkButton last = new LinkButton();
601
last.ID = "Last";
602
last.Click += new EventHandler(last_Click);
603
last.Font.Name = "webdings";
604
last.Font.Size = FontUnit.Medium;
605
last.ForeColor = ForeColor;
606
last.ToolTip = "Last page";
607
last.Text = "8";
608
last.Enabled = isValidPage && canMoveForward;
609
cell.Controls.Add(last);
610
}
611
// ***********************************************************************
612
#endregion
613
614
BuildNumericPagesUI#region BuildNumericPagesUI
615
// ***********************************************************************
616
// PRIVATE BuildNumericPagesUI
617
// Generates the HTML markup for the Numeric Pages button bar
618
private void BuildNumericPagesUI(TableCell cell)
619
{
620
// Render a drop-down list
621
DropDownList pageList = new DropDownList();
622
pageList.ID = "PageList";
623
pageList.AutoPostBack = true;
624
pageList.SelectedIndexChanged += new EventHandler(PageList_Click);
625
pageList.Font.Name = Font.Name;
626
pageList.Font.Size = Font.Size;
627
pageList.ForeColor = ForeColor;
628
629
// Embellish the list when there are no pages to list
630
if (TotalPages <=0 || CurrentPageIndex == -1)
631
{
632
pageList.Items.Add("No pages");
633
pageList.Enabled = false;
634
pageList.SelectedIndex = 0;
635
}
636
else // Populate the list
637
{
638
for(int i=1; i<=TotalPages; i++)
639
{
640
ListItem item = new ListItem(i.ToString(), (i-1).ToString());
641
pageList.Items.Add(item);
642
}
643
pageList.SelectedIndex = CurrentPageIndex;
644
}
645
cell.Controls.Add(pageList);
646
}
647
// ***********************************************************************
648
#endregion
649
650
方法 建立跳转到指定页面#region 方法 建立跳转到指定页面
651
// ***********************************************************************
652
// 方法 建立跳转到指定页面
653
private void BuildGotoPage(TableCell cell)
654
{
655
// bool isValidPage = (CurrentPageIndex >=0 && CurrentPageIndex <= TotalPages-1);
656
657
//跳转到页面索引输入框
658
TextBox txbPage = new TextBox();
659
txbPage.ID = "txbPage";
660
txbPage.Width = 50;
661
txbPage.MaxLength = 5;
662
cell.Controls.Add(txbPage);
663
664
//加空格
665
cell.Controls.Add(new LiteralControl(" "));
666
667
//跳转到按钮
668
Button btnGo = new Button();
669
btnGo.ID = "btnGo";
670
btnGo.Text = "确定";
671
btnGo.BorderStyle = BorderStyle.Ridge;
672
btnGo.BorderWidth = 1;
673
btnGo.CausesValidation = false;
674
btnGo.Click += new EventHandler(btnGo_Click);
675
// btnGo.Enabled = isValidPage;
676
cell.Controls.Add(btnGo);
677
678
}
679
// ***********************************************************************
680
#endregion
681
682
方法 当前页索引#region 方法 当前页索引
683
// ***********************************************************************
684
// 方法 当前页索引
685
// 从0开始
686
private void BuildCurrentPage(TableCell cell)
687
{
688
Label lblIndex = new Label();
689
string temp = "";
690
691
// Use a standard template: Page X of Y
692
if (CurrentPageIndex <0 || CurrentPageIndex >= TotalPages)
693
{
694
temp = NoPageSelectedText;
695
}
696
else
697
{
698
temp = String.Format(CurrentPageText, IndexColor.Name, (CurrentPageIndex+1), TotalPages, TotalRecords, ItemsPerPage);
699
}
700
701
lblIndex.Text = temp;
702
cell.Controls.Add(lblIndex);
703
704
}
705
// ***********************************************************************
706
#endregion
707
708
方法 验证当前页面索引是否有效#region 方法 验证当前页面索引是否有效
709
// ***********************************************************************
710
/**//**//**//// <summary>
711
/// 方法 验证索引是否有效
712
/// 确定当前页面索引范围:[0,TotalPages) or -1
713
/// </summary>
714
private void ValidatePageIndex()
715
{
716
//如果当前页记录删除,跳到前一页
717
if(CurrentPageIndex == TotalPages)
718
{
719
CurrentPageIndex -= 1;
720
}
721
if (!(CurrentPageIndex >=0 && CurrentPageIndex < TotalPages))
722
CurrentPageIndex = -1;
723
return;
724
}
725
// ***********************************************************************
726
#endregion
727
728
方法 获取全部数据(未使用)#region 方法 获取全部数据(未使用)
729
// ***********************************************************************
730
// PRIVATE FetchAllData
731
// Runs the query for all data to be paged and caches the resulting data
732
private void FetchAllData()
733
{
734
// Looks for data in the ASP.NET Cache
735
DataTable data;
736
data = (DataTable) Page.Cache[CacheKeyName];
737
if (data == null)
738
{
739
// Fix SelectCommand with order-by info
740
AdjustSelectCommand(true);
741
742
// If data expired or has never been fetched, go to the database
743
SqlDataAdapter adapter = new SqlDataAdapter(SelectCommand, ConnectionString);
744
data = new DataTable();
745
adapter.Fill(data);
746
Page.Cache.Insert(CacheKeyName, data, null,
747
DateTime.Now.AddSeconds(CacheDuration),
748
System.Web.Caching.Cache.NoSlidingExpiration);
749
}
750
751
// Configures the paged data source component
752
if (_dataSource == null)
753
_dataSource = new PagedDataSource();
754
_dataSource.DataSource = data.DefaultView; // must be IEnumerable!
755
// _dataSource.AllowPaging = true;
756
_dataSource.PageSize = ItemsPerPage;
757
TotalPages = _dataSource.PageCount;
758
TotalRecords = _dataSource.Count;
759
760
// Ensures the page index is valid
761
ValidatePageIndex();
762
if (CurrentPageIndex == -1)
763
{
764
_dataSource = null;
765
return;
766
}
767
768
// Selects the page to view
769
_dataSource.CurrentPageIndex = CurrentPageIndex;
770
}
771
// ***********************************************************************
772
#endregion
773
774
方法 获取当前页面数据#region 方法 获取当前页面数据
775
// ***********************************************************************
776
/**//**//**//// <summary>
777
/// 方法 获取当前页面数据
778
/// </summary>
779
private void FetchPageData()
780
{
781
// 必须获得一个有效的页面索引
782
// 还需要虚拟页面记录统计来验证页面索引
783
AdjustSelectCommand(false);
784
VirtualRecordCount countInfo = CalculateVirtualRecordCount();
785
TotalPages = countInfo.PageCount;
786
TotalRecords = countInfo.RecordCount;
787
788
// 验证页面索引值的有效性(当前页面索引必须有效或为-1)
789
ValidatePageIndex();
790
if (CurrentPageIndex == -1)
791
{
792
CurrentPageIndex = 0;
793
// return;
794
}
795
796
// 准备,运行数据库查询
797
SqlCommand cmd = PrepareCommand(countInfo);
798
if (cmd == null)
799
return;
800
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
801
DataTable data = new DataTable();
802
adapter.Fill(data);
803
804
// 配置翻页数据源组件
805
if (_dataSource == null)
806
_dataSource = new PagedDataSource();
807
//如果不注释下面两行,在datagrid中会出错
808
//2005/12/02 by kevin@wuxi
809
// _dataSource.AllowCustomPaging = true;
810
// _dataSource.AllowPaging = true;
811
_dataSource.CurrentPageIndex = 0;
812
_dataSource.PageSize = ItemsPerPage;
813
_dataSource.VirtualCount = countInfo.RecordCount;
814
_dataSource.DataSource = data.DefaultView;
815
}
816
// ***********************************************************************
817
#endregion
818
819
方法 调整查询语句#region 方法 调整查询语句
820
// ***********************************************************************
821
/**//**//**//// <summary>
822
/// 方法 调整查询语句
823
/// 去除查询语句中的ORDER-BY字句,改用SortField代替排序
824
/// </summary>
825
/// <param name="addCustomSortInfo"></param>
826
private void AdjustSelectCommand(bool addCustomSortInfo)
827
{
828
// 截去查询语句中的 ORDER BY 子句
829
string temp = SelectCommand.ToLower();
830
int pos = temp.IndexOf("order by");
831
if (pos > -1)
832
SelectCommand = SelectCommand.Substring(0, pos);
833
834
// 如果定义了SortField,则加上排序
835
if (SortField != "" && addCustomSortInfo)
836
SelectCommand += " ORDER BY " + SortField;
837
}
838
// ***********************************************************************
839
#endregion
840
841
方法 计算记录统计#region 方法 计算记录统计
842
// ***********************************************************************
843
/**//**//**//// <summary>
844
/// 方法 计算记录统计
845
/// 计算指定查询的记录及页面数
846
/// </summary>
847
/// <returns>记录统计</returns>
848
private VirtualRecordCount CalculateVirtualRecordCount()
849
{
850
VirtualRecordCount count = new VirtualRecordCount();
851
852
// 计算记录数
853
count.RecordCount = GetQueryVirtualCount();
854
count.RecordsInLastPage = ItemsPerPage;
855
856
// 计算交互记录信息
857
int lastPage = count.RecordCount/ItemsPerPage;
858
int remainder = count.RecordCount % ItemsPerPage;
859
if (remainder >0)
860
lastPage++;
861
count.PageCount = lastPage;
862
863
// 计算最后一页的记录数
864
if (remainder >0)
865
count.RecordsInLastPage = remainder;
866
return count;
867
}
868
// ***********************************************************************
869
#endregion
870
871
方法 格式化查询语句#region 方法 格式化查询语句
872
// ***********************************************************************
873
/**//**//**//// <summary>
874
/// 方法 格式化查询语句
875
/// </summary>
876
/// <param name="countInfo">记录统计</param>
877
/// <returns>command对象</returns>
878
private SqlCommand PrepareCommand(VirtualRecordCount countInfo)
879
{
880
// 如排序字段没有定义
881
if (SortField == "")
882
{
883
// Get metadata for all columns and choose either the primary key
884
// or the
885
// 取得所有列的数据,并取任意一列数据为主键
886
string text = "SET FMTONLY ON;" + SelectCommand + ";SET FMTONLY OFF;";
887
SqlDataAdapter adapter = new SqlDataAdapter(text, ConnectionString);
888
DataTable t = new DataTable();
889
adapter.MissingSchemaAction = MissingSchemaAction.AddWithKey;
890
adapter.Fill(t);
891
DataColumn col = null;
892
if (t.PrimaryKey.Length >0)
893
col = t.PrimaryKey[0];
894
else
895
col = t.Columns[0];
896
SortField = col.ColumnName;
897
}
898
899
// 确定要得到多少条数据
900
// 最后一页的数据不会多于前页
901
int recsToRetrieve = ItemsPerPage;
902
if (CurrentPageIndex == countInfo.PageCount-1)
903
recsToRetrieve = countInfo.RecordsInLastPage;
904
905
string cmdText = String.Format(QueryPageCommandText,
906
recsToRetrieve, // {0} --> page size
907
ItemsPerPage*(CurrentPageIndex+1), // {1} --> size * index
908
SelectCommand, // {2} --> base query
909
SortField, // {3} --> key field in the query
910
SortMode, // {4} --> 排序模式
911
AlterSortMode(SortMode));
912
913
SqlConnection conn = new SqlConnection(ConnectionString);
914
SqlCommand cmd = new SqlCommand(cmdText, conn);
915
return cmd;
916
}
917
918
// ***********************************************************************
919
#endregion
920
921
方法 取得总记录条数#region 方法 取得总记录条数
922
// ***********************************************************************
923
/**//**//**//// <summary>
924
/// 方法 取得总记录条数
925
/// </summary>
926
/// <returns>总记录条数</returns>
927
private int GetQueryVirtualCount()
928
{
929
string cmdText = String.Format(QueryCountCommandText, SelectCommand);
930
SqlConnection conn = new SqlConnection(ConnectionString);
931
SqlCommand cmd = new SqlCommand(cmdText, conn);
932
933
cmd.Connection.Open();
934
int recCount = (int) cmd.ExecuteScalar();
935
cmd.Connection.Close();
936
937
return recCount;
938
}
939
// ***********************************************************************
940
#endregion
941
942
方法 跳转到指定页面#region 方法 跳转到指定页面
943
// ***********************************************************************
944
/**//**//**//// <summary>
945
/// 方法 跳转到指定页面
946
/// </summary>
947
/// <param name="pageIndex">页面索引</param>
948
private void GoToPage(int pageIndex)
949
{
950
// 准备事件数据
951
PageChangedEventArgs e = new PageChangedEventArgs();
952
e.OldPageIndex = CurrentPageIndex;
953
e.NewPageIndex = pageIndex;
954
955
// 更新当前页面索引
956
CurrentPageIndex = pageIndex;
957
958
// 触发页面改变事件
959
OnPageIndexChanged(e);
960
961
// 绑定新的数据
962
DataBind();
963
}
964
// ***********************************************************************
965
#endregion
966
967
方法 跳转到第一页#region 方法 跳转到第一页
968
// ***********************************************************************
969
/**//**//**//// <summary>
970
/// 方法 跳转到第一页
971
/// </summary>
972
/// <param name="sender"></param>
973
/// <param name="e"></param>
974
private void first_Click(object sender, EventArgs e)
975
{
976
GoToPage(0);
977
}
978
// ***********************************************************************
979
#endregion
980
981
方法 跳转到前一页#region 方法 跳转到前一页
982
// ***********************************************************************
983
/**//**//**//// <summary>
984
/// 方法 跳转到前一页
985
/// </summary>
986
/// <param name="sender"></param>
987
/// <param name="e"></param>
988
private void prev_Click(object sender, EventArgs e)
989
{
990
GoToPage(CurrentPageIndex-1);
991
}
992
// ***********************************************************************
993
#endregion
994
995
方法 跳转到后一页#region 方法 跳转到后一页
996
// ***********************************************************************
997
/**//**//**//// <summary>
998
/// 方法 跳转到后一页
999
/// </summary>
1000
/// <param name="sender"></param>
1001
/// <param name="e"></param>
1002
private void next_Click(object sender, EventArgs e)
1003
{
1004
GoToPage(CurrentPageIndex+1);
1005
}
1006
// ***********************************************************************
1007
#endregion
1008
1009
方法 跳转到最后一页#region 方法 跳转到最后一页
1010
// ***********************************************************************
1011
/**//**//**//// <summary>
1012
/// 方法 跳转到最后一页
1013
/// </summary>
1014
/// <param name="sender"></param>
1015
/// <param name="e"></param>
1016
private void last_Click(object sender, EventArgs e)
1017
{
1018
GoToPage(TotalPages-1);
1019
}
1020
// ***********************************************************************
1021
#endregion
1022
1023
方法 页面索引选择列表点击#region 方法 页面索引选择列表点击
1024
// ***********************************************************************
1025
/**//**//**//// <summary>
1026
/// 方法 页面索引选择列表点击
1027
/// 通过下拉框选择页面索引
1028
/// </summary>
1029
/// <param name="sender"></param>
1030
/// <param name="e"></param>
1031
private void PageList_Click(object sender, EventArgs e)
1032
{
1033
DropDownList pageList = (DropDownList) sender;
1034
int pageIndex = Convert.ToInt32(pageList.SelectedItem.Value);
1035
GoToPage(pageIndex);
1036
}
1037
// ***********************************************************************
1038
#endregion
1039
1040
方法 反转排序模式#region 方法 反转排序模式
1041
// ***********************************************************************
1042
/**//**//**//// <summary>
1043
/// 方法 反转排序模式
1044
/// </summary>
1045
/// <param name="mode">排序模式</param>
1046
/// <returns>相反的排序模式</returns>
1047
private SortMode AlterSortMode(SortMode mode)
1048
{
1049
if(mode == SortMode.DESC)
1050
{
1051
mode = SortMode.ASC;
1052
}
1053
else
1054
{
1055
mode = SortMode.DESC;
1056
}
1057
return mode;
1058
1059
}
1060
// ***********************************************************************
1061
#endregion
1062
1063
方法 跳转到指定页面按钮点击#region 方法 跳转到指定页面按钮点击
1064
// ***********************************************************************
1065
/**//**//**//// <summary>
1066
/// 方法 跳转到指定页面按钮点击
1067
/// </summary>
1068
/// <param name="sender"></param>
1069
/// <param name="e"></param>
1070
private void btnGo_Click(object sender, EventArgs e)
1071
{
1072
// bool isValidPage = (CurrentPageIndex >=0 && CurrentPageIndex < TotalPages);
1073
1074
TextBox txbpage = (TextBox)FindControl("txbPage");
1075
if(txbpage.Text.Length > 0)
1076
{
1077
int page = Convert.ToInt32(txbpage.Text.Trim());
1078
1079
bool isValidPage = (page -1 >= 0 && page -1 < TotalPages);
1080
if(isValidPage == true)
1081
{
1082
GoToPage(page -1);
1083
}
1084
}
1085
}
1086
// ***********************************************************************
1087
#endregion
1088
1089
1090
#endregion
1091
}
1092
#endregion
1093
}
1094
using System;2
using System.IO;3
using System.Drawing;4
using System.Data;5
using System.Data.SqlClient;6
using System.Web.UI;7
using System.Web.UI.WebControls;8
using System.ComponentModel;9
using System.Configuration;10

11
namespace DevCenter12


{13

枚举 缓存模式#region 枚举 缓存模式14
public enum PagingMode15

{16
//缓存17
Cached,18
//不缓存19
NonCached 20
}21
#endregion22
23

枚举 导航条样式#region 枚举 导航条样式24
public enum PagerStyle25

{26
Character,27
NextPrev,28
NumericPages29
}30
#endregion31

32

枚举 排序模式#region 枚举 排序模式33
public enum SortMode34

{35
ASC,36
DESC37
}38
#endregion39

40

类 记录统计#region 类 记录统计41
public class VirtualRecordCount42

{43
public int RecordCount;44
public int PageCount;45
//最后一页的记录数46
public int RecordsInLastPage;47
}48
#endregion49

50

类 页面改变事件参数#region 类 页面改变事件参数51
public class PageChangedEventArgs : EventArgs 52

{53
public int OldPageIndex;54
public int NewPageIndex;55
}56
#endregion 57

58

SqlPager分页控件#region SqlPager分页控件59

60
[DefaultProperty("SelectCommand")]61
[DefaultEvent("PageIndexChanged")]62
[ToolboxData("<{0}:SqlPager runat=\"server\" />")]63
public class SqlPager : WebControl, INamingContainer64

{65

私有成员#region 私有成员66
// ***********************************************************************67
// 私有成员68

69
//数据源70
private PagedDataSource _dataSource;71
//数据容器72
private Control _controlToPaginate;73
private string CacheKeyName 74

{75

get
{return Page.Request.FilePath + "_" + UniqueID + "_Data";}76
}77
//导航条页面信息显示78
private string CurrentPageText = "当前第<font color={0}>{1}</font>页 共分<font color={0}>{2}</font>页 总计<font color={0}>{3}</font>条 每页<font color={0}>{4}</font>条";79
//导航条无记录显示80
private string NoPageSelectedText = "没有记录!";81
//格式化sql查询语句82
private string QueryPageCommandText = "SELECT * FROM " + 83
"(SELECT TOP {0} * FROM " + 84
"(SELECT TOP {1} * FROM ({2}) AS t0 ORDER BY {3} {4}) AS t1 " + 85
"ORDER BY {3} {5}) AS t2 " + 86
"ORDER BY {3} {4}";87
//格式化sql记录统计语句88
private string QueryCountCommandText = "SELECT COUNT(*) FROM ({0}) AS t0";89
// ***********************************************************************90
#endregion91

92

构造器#region 构造器93
// ***********************************************************************94
// 构造器95
public SqlPager() : base()96

{97
_dataSource = null;98
_controlToPaginate = null;99

100
Font.Name = "verdana";101
Font.Size = FontUnit.Point(9);102
BackColor = Color.Gainsboro; 103
ForeColor = Color.Black;104
IndexColor = Color.Black;105
BorderStyle = BorderStyle.Outset;106
BorderWidth = Unit.Parse("1px"); 107
PagingMode = PagingMode.NonCached;108
PagerStyle = PagerStyle.Character;109
CurrentPageIndex = 0;110
SelectCommand = "";111
ConnectionString = "";112
ItemsPerPage = 15;113
TotalPages = -1;114
CacheDuration = 60;115
SortMode = SortMode.DESC;116
ConnectionString = ConfigurationSettings.AppSettings["CONN_STR"];117
}118
// ***********************************************************************119
#endregion120

121

公共程序接口#region 公共程序接口122

123

124

方法 清空缓存#region 方法 清空缓存125

/**//**//**//// <summary>126
/// 方法 清空缓存127
/// </summary>128
public void ClearCache()129

{130
if (PagingMode == PagingMode.Cached)131
Page.Cache.Remove(CacheKeyName); 132
}133
#endregion134

135

136

事件 页面索引改变#region 事件 页面索引改变137
// ***********************************************************************138

/**//**//**//// <summary>139
/// 事件 页面索引改变140
/// 当跳转到新页面时发生141
/// </summary>142
public delegate void PageChangedEventHandler(object sender, PageChangedEventArgs e);143
public event PageChangedEventHandler PageIndexChanged;144
protected virtual void OnPageIndexChanged(PageChangedEventArgs e)145

{146
if (PageIndexChanged != null)147
PageIndexChanged(this, e);148
}149
// ***********************************************************************150
#endregion151

152

153

属性 缓存过期时间#region 属性 缓存过期时间154
// ***********************************************************************155
// 属性 缓存过期时间156
[Description("取得或设置数据在缓存中保存多少秒")]157
public int CacheDuration158

{159

get
{return Convert.ToInt32(ViewState["CacheDuration"]);}160

set
{ViewState["CacheDuration"] = value;}161
}162
// ***********************************************************************163
#endregion164

165

属性 缓存模式#region 属性 缓存模式166
// ***********************************************************************167
// 属性 缓存模式168
[Description("指定数据是否需要在页面上缓存")]169
public PagingMode PagingMode170

{171

get
{return (PagingMode) ViewState["PagingMode"];}172

set
{ViewState["PagingMode"] = value;}173
}174
// ***********************************************************************175
#endregion176

177

属性 导航条样式#region 属性 导航条样式178
// ***********************************************************************179
// 属性 导航条样式180
[Description("指定导航条样式")]181
public PagerStyle PagerStyle182

{183

get
{return (PagerStyle) ViewState["PagerStyle"];}184

set
{ViewState["PagerStyle"] = value;}185
}186
// ***********************************************************************187
#endregion188

189

属性 索引值颜色#region 属性 索引值颜色190
// ***********************************************************************191
// 属性 索引值颜色192
[Description("指定索引值颜色")]193
public Color IndexColor194

{195

get
{return (Color) ViewState["IndexColor"];}196

set
{ViewState["IndexColor"] = value;}197
}198
// ***********************************************************************199
#endregion200

201

属性 数据容器#region 属性 数据容器202
// ***********************************************************************203
// 属性 数据容器204
[Description("取得设置数据容器的名字")]205
public string ControlToPaginate206

{207

get
{return Convert.ToString(ViewState["ControlToPaginate"]);}208

set
{ViewState["ControlToPaginate"] = value;}209
}210
// ***********************************************************************211
#endregion212

213

属性 每页记录数#region 属性 每页记录数214
// ***********************************************************************215
// 属性 每页记录数216
[Description("取得设置每页显示的记录数")]217
public int ItemsPerPage218

{219

get
{return Convert.ToInt32(ViewState["ItemsPerPage"]);}220

set
{ViewState["ItemsPerPage"] = value;}221
}222
// ***********************************************************************223
#endregion224

225

属性 当前页索引#region 属性 当前页索引226
// ***********************************************************************227
// 属性 当前页索引228
[Description("取得设置当前页面索引")]229
public int CurrentPageIndex230

{231

get
{return Convert.ToInt32(ViewState["CurrentPageIndex"]);}232

set
{ViewState["CurrentPageIndex"] = value;}233
}234
// ***********************************************************************235
#endregion236

237

属性 连接字符串#region 属性 连接字符串238
// ***********************************************************************239
// 属性 连接字符串240
[Description("取得设置数据库连接字符串")]241
public string ConnectionString242

{243

get
{return Convert.ToString(ViewState["ConnectionString"]);}244

set
{ViewState["ConnectionString"] = value;}245
}246
// ***********************************************************************247
#endregion248

249

属性 查询语句#region 属性 查询语句250
// ***********************************************************************251
// 属性 查询语句252
[Description("取得设置数据库查询语句")]253
public string SelectCommand254

{255

get
{return Convert.ToString(ViewState["SelectCommand"]);}256

set
{ViewState["SelectCommand"] = value;}257
}258
// ***********************************************************************259
#endregion260

261

属性 排序字段#region 属性 排序字段262
// ***********************************************************************263
// 属性 排序字段264
[Description("取得设置排序字段,仅在无缓存的模式下可用")]265
public string SortField266

{267

get
{return Convert.ToString(ViewState["SortKeyField"]);}268

set
{ViewState["SortKeyField"] = value;}269
}270
// ***********************************************************************271
#endregion272

273

属性 总页数#region 属性 总页数274
// ***********************************************************************275
// 属性 总页数276
// 取得显示页面的总数277
[Browsable(false)]278
public int PageCount279

{280

get
{return TotalPages;}281
}282
// ***********************************************************************283
#endregion284

285

属性 总页数#region 属性 总页数286
// ***********************************************************************287
// 属性 总页数288
// 取得设置显示页面的总数289
protected int TotalPages290

{291

get
{return Convert.ToInt32(ViewState["TotalPages"]);}292

set
{ViewState["TotalPages"] = value;}293
}294
// ***********************************************************************295
#endregion296

297

属性 总记录数#region 属性 总记录数298
// ***********************************************************************299
// 属性 总记录数300
// 取得设置总记录数301
protected int TotalRecords302

{303

get
{return Convert.ToInt32(ViewState["TotalRecords"]);}304

set
{ViewState["TotalRecords"] = value;}305
}306
// ***********************************************************************307
#endregion308

309

属性 排序模式#region 属性 排序模式310
// ***********************************************************************311
// 属性 排序模式312
[Description("取得设置排序模式")]313
public SortMode SortMode314

{315

get
{return (SortMode) ViewState["SortMode"];}316

set
{ViewState["SortMode"] = value;}317
}318
// ***********************************************************************319
#endregion320

321

322

方法 重载 数据绑定#region 方法 重载 数据绑定323
// ***********************************************************************324
// 方法 重载数据绑定325

/**//**//**//// <summary>326
/// 取得,填充数据327
/// </summary>328
public override void DataBind()329

{330
// 触发数据绑定事件331
base.DataBind();332

333
// 控件必须在数据绑定后重新创建334
ChildControlsCreated = false;335

336
// 确定数据容器存在并且为列表控件(list control)337
if (ControlToPaginate == "")338
return;339
_controlToPaginate = Page.FindControl(ControlToPaginate);340
if (_controlToPaginate == null)341
return;342
if (!(_controlToPaginate is BaseDataList || _controlToPaginate is ListControl))343
return;344

345
// 确定数据库连接字符串有效且查询命令已指定346
if (ConnectionString == "" || SelectCommand == "")347
return;348

349
// 取得数据350
if (PagingMode == PagingMode.Cached)351
FetchAllData();352
else353

{354
//if (SortField == "")355
// return;356
FetchPageData();357
}358

359
// Bind data to the buddy control360
// 绑定数据到数据容器361
BaseDataList baseDataListControl = null;362
ListControl listControl = null;363
if (_controlToPaginate is BaseDataList)364

{365
baseDataListControl = (BaseDataList) _controlToPaginate;366
baseDataListControl.DataSource = _dataSource; 367
baseDataListControl.DataBind();368
return;369
}370
if (_controlToPaginate is ListControl)371

{372
listControl = (ListControl) _controlToPaginate;373
listControl.Items.Clear(); 374
listControl.DataSource = _dataSource; 375
listControl.DataBind();376
return;377
}378
}379
// ***********************************************************************380
#endregion381

382

方法 重载 传递数据#region 方法 重载 传递数据383
// ***********************************************************************384
// 方法 重载 传递数据385
// 把数据内容传递到客户端386
protected override void Render(HtmlTextWriter output)387

{388
// If in design-mode ensure that child controls have been created.389
// Child controls are not created at this time in design-mode because390
// there's no pre-render stage. Do so for composite controls like this 391
if (Site != null && Site.DesignMode) 392
CreateChildControls();393

394
base.Render(output);395
}396
// ***********************************************************************397
#endregion398

399

方法 重载 创建子控件#region 方法 重载 创建子控件400
// ***********************************************************************401
// 方法 重载 创建子控件402
// Outputs the HTML markup for the control403
protected override void CreateChildControls()404

{405
Controls.Clear();406
ClearChildViewState();407

408
BuildControlHierarchy();409
}410
// ***********************************************************************411
#endregion412

413

414
#endregion415

416

私有方法#region 私有方法417

418

方法 创建导航条#region 方法 创建导航条419
// ***********************************************************************420
// 方法 创建导航条421
private void BuildControlHierarchy()422

{423
// 导航条表格,1行2列424
Table t = new Table();425
t.Font.Name = Font.Name;426
t.Font.Size = Font.Size;427
t.BorderStyle = BorderStyle;428
t.BorderWidth = BorderWidth;429
t.BorderColor = BorderColor;430
t.Width = Width;431
t.Height = Height;432
t.BackColor = BackColor;433
t.ForeColor = ForeColor;434

435
// 表格行436
TableRow row = new TableRow();437
t.Rows.Add(row);438

439
// 页面索引单元格440
TableCell cellPageDesc = new TableCell();441
cellPageDesc.HorizontalAlign = HorizontalAlign.Right;442
BuildCurrentPage(cellPageDesc);443
row.Cells.Add(cellPageDesc);444

445
// 导航按钮单元格446
TableCell cellNavBar = new TableCell();447

448
switch(PagerStyle)449

{450
//字符导航条451
case PagerStyle.Character:452
BuildCharacterUI(cellNavBar);453
break;454
case PagerStyle.NextPrev:455
BuildNextPrevUI(cellNavBar);456
break;457
case PagerStyle.NumericPages:458
BuildNumericPagesUI(cellNavBar);459
break;460
default:461
break;462
}463

464
row.Cells.Add(cellNavBar);465

466
TableCell cellTip = new TableCell();467
cellTip.Text = "跳转到";468
row.Cells.Add(cellTip);469

470
//跳转到指定页输入框和按钮471
TableCell cellGotoPage = new TableCell();472
BuildGotoPage(cellGotoPage);473
row.Cells.Add(cellGotoPage);474

475
// 把表格加入到控件树476
Controls.Add(t);477
}478
// ***********************************************************************479
#endregion480

481

建立字符导航栏#region 建立字符导航栏482

/**//**//**//// <summary>483
/// 建立字符导航栏484
/// </summary>485
/// <param name="cell"></param>486
private void BuildCharacterUI(TableCell cell)487

{488
bool isValidPage = (CurrentPageIndex >=0 && CurrentPageIndex <= TotalPages-1);489
bool canMoveBack = (CurrentPageIndex>0);490
bool canMoveForward = (CurrentPageIndex<TotalPages-1);491

492
//定义首页按钮式样493
LinkButton first = new LinkButton();494
first.ID = "First";495
first.CausesValidation = false;496
first.Click += new EventHandler(first_Click);497
first.ToolTip = "首页";498
first.Text = "首页";499
first.Enabled = isValidPage && canMoveBack;500
cell.Controls.Add(first);501

502
//加空格503
cell.Controls.Add(new LiteralControl(" "));504

505
//定义前页按钮式样506
LinkButton prev = new LinkButton();507
prev.ID = "Prev";508
prev.CausesValidation = false;509
prev.Click += new EventHandler(prev_Click);510
prev.ToolTip = "前页";511
prev.Text = "前页"; 512
prev.Enabled = isValidPage && canMoveBack;513
cell.Controls.Add(prev);514

515
//加空格516
cell.Controls.Add(new LiteralControl(" "));517

518
//定义后页按钮式样519
LinkButton next = new LinkButton();520
next.ID = "Next";521
next.CausesValidation = false;522
next.Click += new EventHandler(next_Click);523
next.ToolTip = "后页";524
next.Text = "后页"; 525
next.Enabled = isValidPage && canMoveForward;526
cell.Controls.Add(next);527

528
//加空格529
cell.Controls.Add(new LiteralControl(" "));530

531
//定义尾页按钮式样532
LinkButton last = new LinkButton();533
last.ID = "Last";534
last.CausesValidation = false;535
last.Click += new EventHandler(last_Click);536
last.ToolTip = "尾页";537
last.Text = "尾页";538
last.Enabled = isValidPage && canMoveForward;539
cell.Controls.Add(last);540
}541
// ***********************************************************************542
#endregion543

544

BuildNextPrevUI#region BuildNextPrevUI545
// ***********************************************************************546
// PRIVATE BuildNextPrevUI547
// Generates the HTML markup for the Next/Prev navigation bar548
private void BuildNextPrevUI(TableCell cell)549

{550
bool isValidPage = (CurrentPageIndex >=0 && CurrentPageIndex <= TotalPages-1);551
bool canMoveBack = (CurrentPageIndex>0);552
bool canMoveForward = (CurrentPageIndex<TotalPages-1);553

554
// Render the << button555
LinkButton first = new LinkButton();556
first.ID = "First";557
first.Click += new EventHandler(first_Click);558
first.Font.Name = "webdings";559
first.Font.Size = FontUnit.Medium;560
first.ForeColor = ForeColor;561
first.ToolTip = "First page";562
first.Text = "7"; 563
first.Enabled = isValidPage && canMoveBack;564
cell.Controls.Add(first);565

566
// Add a separator567
cell.Controls.Add(new LiteralControl(" "));568

569
// Render the < button570
LinkButton prev = new LinkButton();571
prev.ID = "Prev";572
prev.Click += new EventHandler(prev_Click);573
prev.Font.Name = "webdings";574
prev.Font.Size = FontUnit.Medium;575
prev.ForeColor = ForeColor;576
prev.ToolTip = "Previous page";577
prev.Text = "3"; 578
prev.Enabled = isValidPage && canMoveBack;579
cell.Controls.Add(prev);580

581
// Add a separator582
cell.Controls.Add(new LiteralControl(" "));583

584
// Render the > button585
LinkButton next = new LinkButton();586
next.ID = "Next";587
next.Click += new EventHandler(next_Click);588
next.Font.Name = "webdings";589
next.Font.Size = FontUnit.Medium;590
next.ForeColor = ForeColor;591
next.ToolTip = "Next page";592
next.Text = "4"; 593
next.Enabled = isValidPage && canMoveForward;594
cell.Controls.Add(next);595

596
// Add a separator597
cell.Controls.Add(new LiteralControl(" "));598

599
// Render the >> button600
LinkButton last = new LinkButton();601
last.ID = "Last";602
last.Click += new EventHandler(last_Click);603
last.Font.Name = "webdings";604
last.Font.Size = FontUnit.Medium;605
last.ForeColor = ForeColor;606
last.ToolTip = "Last page";607
last.Text = "8";608
last.Enabled = isValidPage && canMoveForward;609
cell.Controls.Add(last);610
}611
// ***********************************************************************612
#endregion613

614

BuildNumericPagesUI#region BuildNumericPagesUI615
// ***********************************************************************616
// PRIVATE BuildNumericPagesUI617
// Generates the HTML markup for the Numeric Pages button bar618
private void BuildNumericPagesUI(TableCell cell)619

{620
// Render a drop-down list 621
DropDownList pageList = new DropDownList();622
pageList.ID = "PageList";623
pageList.AutoPostBack = true;624
pageList.SelectedIndexChanged += new EventHandler(PageList_Click);625
pageList.Font.Name = Font.Name;626
pageList.Font.Size = Font.Size;627
pageList.ForeColor = ForeColor;628

629
// Embellish the list when there are no pages to list 630
if (TotalPages <=0 || CurrentPageIndex == -1)631

{632
pageList.Items.Add("No pages");633
pageList.Enabled = false;634
pageList.SelectedIndex = 0; 635
}636
else // Populate the list637

{638
for(int i=1; i<=TotalPages; i++)639

{640
ListItem item = new ListItem(i.ToString(), (i-1).ToString());641
pageList.Items.Add(item);642
}643
pageList.SelectedIndex = CurrentPageIndex;644
}645
cell.Controls.Add(pageList);646
}647
// ***********************************************************************648
#endregion649

650

方法 建立跳转到指定页面#region 方法 建立跳转到指定页面651
// ***********************************************************************652
// 方法 建立跳转到指定页面653
private void BuildGotoPage(TableCell cell)654

{655
// bool isValidPage = (CurrentPageIndex >=0 && CurrentPageIndex <= TotalPages-1);656

657
//跳转到页面索引输入框658
TextBox txbPage = new TextBox();659
txbPage.ID = "txbPage";660
txbPage.Width = 50;661
txbPage.MaxLength = 5;662
cell.Controls.Add(txbPage);663

664
//加空格665
cell.Controls.Add(new LiteralControl(" "));666

667
//跳转到按钮668
Button btnGo = new Button();669
btnGo.ID = "btnGo";670
btnGo.Text = "确定";671
btnGo.BorderStyle = BorderStyle.Ridge;672
btnGo.BorderWidth = 1;673
btnGo.CausesValidation = false;674
btnGo.Click += new EventHandler(btnGo_Click);675
// btnGo.Enabled = isValidPage;676
cell.Controls.Add(btnGo);677

678
}679
// ***********************************************************************680
#endregion681

682

方法 当前页索引#region 方法 当前页索引683
// ***********************************************************************684
// 方法 当前页索引685
// 从0开始686
private void BuildCurrentPage(TableCell cell)687

{688
Label lblIndex = new Label();689
string temp = "";690

691
// Use a standard template: Page X of Y692
if (CurrentPageIndex <0 || CurrentPageIndex >= TotalPages)693

{694
temp = NoPageSelectedText;695
}696
else697

{698
temp = String.Format(CurrentPageText, IndexColor.Name, (CurrentPageIndex+1), TotalPages, TotalRecords, ItemsPerPage);699
}700

701
lblIndex.Text = temp;702
cell.Controls.Add(lblIndex);703

704
}705
// ***********************************************************************706
#endregion707

708

方法 验证当前页面索引是否有效#region 方法 验证当前页面索引是否有效709
// ***********************************************************************710

/**//**//**//// <summary>711
/// 方法 验证索引是否有效712
/// 确定当前页面索引范围:[0,TotalPages) or -1713
/// </summary>714
private void ValidatePageIndex()715

{716
//如果当前页记录删除,跳到前一页717
if(CurrentPageIndex == TotalPages)718

{719
CurrentPageIndex -= 1;720
}721
if (!(CurrentPageIndex >=0 && CurrentPageIndex < TotalPages))722
CurrentPageIndex = -1;723
return;724
}725
// ***********************************************************************726
#endregion727

728

方法 获取全部数据(未使用)#region 方法 获取全部数据(未使用)729
// ***********************************************************************730
// PRIVATE FetchAllData731
// Runs the query for all data to be paged and caches the resulting data732
private void FetchAllData()733

{734
// Looks for data in the ASP.NET Cache735
DataTable data;736
data = (DataTable) Page.Cache[CacheKeyName];737
if (data == null)738

{739
// Fix SelectCommand with order-by info740
AdjustSelectCommand(true);741

742
// If data expired or has never been fetched, go to the database743
SqlDataAdapter adapter = new SqlDataAdapter(SelectCommand, ConnectionString);744
data = new DataTable();745
adapter.Fill(data);746
Page.Cache.Insert(CacheKeyName, data, null, 747
DateTime.Now.AddSeconds(CacheDuration), 748
System.Web.Caching.Cache.NoSlidingExpiration);749
}750
751
// Configures the paged data source component752
if (_dataSource == null)753
_dataSource = new PagedDataSource(); 754
_dataSource.DataSource = data.DefaultView; // must be IEnumerable!755
// _dataSource.AllowPaging = true;756
_dataSource.PageSize = ItemsPerPage;757
TotalPages = _dataSource.PageCount; 758
TotalRecords = _dataSource.Count;759

760
// Ensures the page index is valid 761
ValidatePageIndex();762
if (CurrentPageIndex == -1)763

{764
_dataSource = null;765
return;766
}767

768
// Selects the page to view769
_dataSource.CurrentPageIndex = CurrentPageIndex;770
}771
// ***********************************************************************772
#endregion773

774

方法 获取当前页面数据#region 方法 获取当前页面数据775
// ***********************************************************************776

/**//**//**//// <summary>777
/// 方法 获取当前页面数据778
/// </summary>779
private void FetchPageData()780

{781
// 必须获得一个有效的页面索引782
// 还需要虚拟页面记录统计来验证页面索引783
AdjustSelectCommand(false);784
VirtualRecordCount countInfo = CalculateVirtualRecordCount();785
TotalPages = countInfo.PageCount;786
TotalRecords = countInfo.RecordCount;787

788
// 验证页面索引值的有效性(当前页面索引必须有效或为-1)789
ValidatePageIndex();790
if (CurrentPageIndex == -1)791

{792
CurrentPageIndex = 0;793
// return;794
}795

796
// 准备,运行数据库查询797
SqlCommand cmd = PrepareCommand(countInfo);798
if (cmd == null)799
return;800
SqlDataAdapter adapter = new SqlDataAdapter(cmd);801
DataTable data = new DataTable();802
adapter.Fill(data);803

804
// 配置翻页数据源组件805
if (_dataSource == null)806
_dataSource = new PagedDataSource();807
//如果不注释下面两行,在datagrid中会出错808
//2005/12/02 by kevin@wuxi809
// _dataSource.AllowCustomPaging = true;810
// _dataSource.AllowPaging = true;811
_dataSource.CurrentPageIndex = 0;812
_dataSource.PageSize = ItemsPerPage;813
_dataSource.VirtualCount = countInfo.RecordCount;814
_dataSource.DataSource = data.DefaultView; 815
}816
// ***********************************************************************817
#endregion818

819

方法 调整查询语句#region 方法 调整查询语句820
// ***********************************************************************821

/**//**//**//// <summary>822
/// 方法 调整查询语句823
/// 去除查询语句中的ORDER-BY字句,改用SortField代替排序824
/// </summary>825
/// <param name="addCustomSortInfo"></param>826
private void AdjustSelectCommand(bool addCustomSortInfo)827

{828
// 截去查询语句中的 ORDER BY 子句829
string temp = SelectCommand.ToLower();830
int pos = temp.IndexOf("order by"); 831
if (pos > -1)832
SelectCommand = SelectCommand.Substring(0, pos);833

834
// 如果定义了SortField,则加上排序835
if (SortField != "" && addCustomSortInfo)836
SelectCommand += " ORDER BY " + SortField;837
}838
// ***********************************************************************839
#endregion840

841

方法 计算记录统计#region 方法 计算记录统计842
// ***********************************************************************843

/**//**//**//// <summary>844
/// 方法 计算记录统计845
/// 计算指定查询的记录及页面数846
/// </summary>847
/// <returns>记录统计</returns>848
private VirtualRecordCount CalculateVirtualRecordCount()849

{850
VirtualRecordCount count = new VirtualRecordCount();851

852
// 计算记录数853
count.RecordCount = GetQueryVirtualCount();854
count.RecordsInLastPage = ItemsPerPage;855

856
// 计算交互记录信息857
int lastPage = count.RecordCount/ItemsPerPage;858
int remainder = count.RecordCount % ItemsPerPage;859
if (remainder >0)860
lastPage++;861
count.PageCount = lastPage;862
863
// 计算最后一页的记录数864
if (remainder >0)865
count.RecordsInLastPage = remainder;866
return count;867
}868
// ***********************************************************************869
#endregion870

871

方法 格式化查询语句#region 方法 格式化查询语句872
// ***********************************************************************873

/**//**//**//// <summary>874
/// 方法 格式化查询语句875
/// </summary>876
/// <param name="countInfo">记录统计</param>877
/// <returns>command对象</returns>878
private SqlCommand PrepareCommand(VirtualRecordCount countInfo)879

{880
// 如排序字段没有定义881
if (SortField == "")882

{883
// Get metadata for all columns and choose either the primary key884
// or the 885
// 取得所有列的数据,并取任意一列数据为主键886
string text = "SET FMTONLY ON;" + SelectCommand + ";SET FMTONLY OFF;";887
SqlDataAdapter adapter = new SqlDataAdapter(text, ConnectionString);888
DataTable t = new DataTable();889
adapter.MissingSchemaAction = MissingSchemaAction.AddWithKey;890
adapter.Fill(t);891
DataColumn col = null;892
if (t.PrimaryKey.Length >0)893
col = t.PrimaryKey[0];894
else895
col = t.Columns[0];896
SortField = col.ColumnName;897
}898

899
// 确定要得到多少条数据900
// 最后一页的数据不会多于前页901
int recsToRetrieve = ItemsPerPage;902
if (CurrentPageIndex == countInfo.PageCount-1)903
recsToRetrieve = countInfo.RecordsInLastPage;904

905
string cmdText = String.Format(QueryPageCommandText, 906
recsToRetrieve, // {0} --> page size907
ItemsPerPage*(CurrentPageIndex+1), // {1} --> size * index908
SelectCommand, // {2} --> base query909
SortField, // {3} --> key field in the query910
SortMode, // {4} --> 排序模式911
AlterSortMode(SortMode));912

913
SqlConnection conn = new SqlConnection(ConnectionString);914
SqlCommand cmd = new SqlCommand(cmdText, conn);915
return cmd;916
}917

918
// ***********************************************************************919
#endregion920

921

方法 取得总记录条数#region 方法 取得总记录条数922
// ***********************************************************************923

/**//**//**//// <summary>924
/// 方法 取得总记录条数925
/// </summary>926
/// <returns>总记录条数</returns>927
private int GetQueryVirtualCount()928

{929
string cmdText = String.Format(QueryCountCommandText, SelectCommand);930
SqlConnection conn = new SqlConnection(ConnectionString);931
SqlCommand cmd = new SqlCommand(cmdText, conn);932

933
cmd.Connection.Open();934
int recCount = (int) cmd.ExecuteScalar(); 935
cmd.Connection.Close();936

937
return recCount;938
}939
// ***********************************************************************940
#endregion941

942

方法 跳转到指定页面#region 方法 跳转到指定页面943
// ***********************************************************************944

/**//**//**//// <summary>945
/// 方法 跳转到指定页面946
/// </summary>947
/// <param name="pageIndex">页面索引</param>948
private void GoToPage(int pageIndex)949

{950
// 准备事件数据951
PageChangedEventArgs e = new PageChangedEventArgs();952
e.OldPageIndex = CurrentPageIndex;953
e.NewPageIndex = pageIndex;954

955
// 更新当前页面索引956
CurrentPageIndex = pageIndex;957

958
// 触发页面改变事件959
OnPageIndexChanged(e);960

961
// 绑定新的数据962
DataBind();963
}964
// ***********************************************************************965
#endregion966

967

方法 跳转到第一页#region 方法 跳转到第一页968
// ***********************************************************************969

/**//**//**//// <summary>970
/// 方法 跳转到第一页971
/// </summary>972
/// <param name="sender"></param>973
/// <param name="e"></param>974
private void first_Click(object sender, EventArgs e)975

{976
GoToPage(0);977
}978
// ***********************************************************************979
#endregion980

981

方法 跳转到前一页#region 方法 跳转到前一页982
// ***********************************************************************983

/**//**//**//// <summary>984
/// 方法 跳转到前一页985
/// </summary>986
/// <param name="sender"></param>987
/// <param name="e"></param>988
private void prev_Click(object sender, EventArgs e)989

{990
GoToPage(CurrentPageIndex-1);991
}992
// ***********************************************************************993
#endregion994

995

方法 跳转到后一页#region 方法 跳转到后一页996
// ***********************************************************************997

/**//**//**//// <summary>998
/// 方法 跳转到后一页999
/// </summary>1000
/// <param name="sender"></param>1001
/// <param name="e"></param>1002
private void next_Click(object sender, EventArgs e)1003

{1004
GoToPage(CurrentPageIndex+1);1005
}1006
// ***********************************************************************1007
#endregion1008

1009

方法 跳转到最后一页#region 方法 跳转到最后一页1010
// ***********************************************************************1011

/**//**//**//// <summary>1012
/// 方法 跳转到最后一页1013
/// </summary>1014
/// <param name="sender"></param>1015
/// <param name="e"></param>1016
private void last_Click(object sender, EventArgs e)1017

{1018
GoToPage(TotalPages-1);1019
}1020
// ***********************************************************************1021
#endregion1022

1023

方法 页面索引选择列表点击#region 方法 页面索引选择列表点击1024
// ***********************************************************************1025

/**//**//**//// <summary>1026
/// 方法 页面索引选择列表点击1027
/// 通过下拉框选择页面索引1028
/// </summary>1029
/// <param name="sender"></param>1030
/// <param name="e"></param>1031
private void PageList_Click(object sender, EventArgs e)1032

{1033
DropDownList pageList = (DropDownList) sender;1034
int pageIndex = Convert.ToInt32(pageList.SelectedItem.Value);1035
GoToPage(pageIndex);1036
}1037
// ***********************************************************************1038
#endregion1039

1040

方法 反转排序模式#region 方法 反转排序模式1041
// ***********************************************************************1042

/**//**//**//// <summary>1043
/// 方法 反转排序模式1044
/// </summary>1045
/// <param name="mode">排序模式</param>1046
/// <returns>相反的排序模式</returns>1047
private SortMode AlterSortMode(SortMode mode)1048

{1049
if(mode == SortMode.DESC)1050

{1051
mode = SortMode.ASC;1052
}1053
else1054

{1055
mode = SortMode.DESC;1056
}1057
return mode;1058
1059
}1060
// ***********************************************************************1061
#endregion1062

1063

方法 跳转到指定页面按钮点击#region 方法 跳转到指定页面按钮点击1064
// ***********************************************************************1065

/**//**//**//// <summary>1066
/// 方法 跳转到指定页面按钮点击1067
/// </summary>1068
/// <param name="sender"></param>1069
/// <param name="e"></param>1070
private void btnGo_Click(object sender, EventArgs e)1071

{1072
// bool isValidPage = (CurrentPageIndex >=0 && CurrentPageIndex < TotalPages);1073

1074
TextBox txbpage = (TextBox)FindControl("txbPage");1075
if(txbpage.Text.Length > 0)1076

{1077
int page = Convert.ToInt32(txbpage.Text.Trim());1078
1079
bool isValidPage = (page -1 >= 0 && page -1 < TotalPages);1080
if(isValidPage == true)1081

{1082
GoToPage(page -1);1083
}1084
}1085
}1086
// ***********************************************************************1087
#endregion1088

1089

1090
#endregion1091
}1092
#endregion1093
}1094


浙公网安备 33010602011771号