轉自:http://blog.rdiframework.net/97.html
關於數據分頁的文章太多了,各有各的一套方案,但大多都很類似,要麼使用存儲過程,要麼直接使用代碼進行分頁。各種方案分頁的效率也不盡相同,我們不一定要找一個最高效的(根據實際的項目情況),找一個最合適的就OK了。下面我要談的分頁控件非常靈活,可以支持任意類型的數據庫,同時可以支持存儲過程或代碼分頁(會自動判斷),也支持多表的分頁,非常的方便。對於數據分頁的相關文章,在我的博客中可以找到很多,下面我做一個簡單的彙總,方便大家查閱。
3、 RDIFramework.NET 中多表關聯查詢分頁實例
下面要給大家分享的分頁控件只做分頁的處理,不做與數據庫相關的操作。直接提供分頁的數據給分頁控件即可。它不關心你的數據來源是什麼,也不關心你採用的數據分頁的方式(存儲過程或代碼等)。這個分頁控件我取名爲:UcPagerEx,如下圖所示:
實現分頁控件的代碼非常的簡單,下面直接給出全部源碼,大家可以參考下,整個分頁控件的源碼如下:
1 using System; 2 using System.ComponentModel; 3 using System.Windows.Forms; 4 namespace RDIFramework.Controls 5 { 6 public delegate void PageChangedEventHandler(object sender, EventArgs e); 7 /// 8 /// 分頁用戶控件,僅提供分頁信息顯示及改變頁碼操作 9 /// 10 public partial class UcPagerEx : UserControl 11 { 12 public event PageChangedEventHandler PageChanged; 13 private int _pageSize; 14 private int m_PageCount; 15 private int _recordCount; 16 private int _pageIndex; 17 18 19 public UcPagerEx() 20 { 21 InitializeComponent(); 22 this._pageSize = 10; 23 this._recordCount = 0; 24 this._pageIndex = 1; //默認爲第一頁 25 } 26 /// 27 /// 帶參數的構造函數 28 /// 每頁記錄數 29 /// 總記錄數 30 /// 31 public UcPagerEx(int recordCount, int pageSize) 32 { 33 InitializeComponent(); 34 35 this._pageSize = pageSize; 36 this._recordCount = recordCount; 37 this._pageIndex = 1; //默認爲第一頁 38 this.InitPageInfo(); 39 } 40 protected virtual void OnPageChanged(EventArgs e) 41 { 42 if (PageChanged != null) 43 { 44 InitPageInfo(); 45 PageChanged(this, e); 46 } 47 } 48 [Description("設置或獲取一頁中顯示的記錄數目"), DefaultValue(20), Category("分頁")] 49 public int PageSize 50 { 51 set 52 { 53 this._pageSize = value; 54 } 55 get 56 { 57 return this._pageSize; 58 } 59 } 60 61 [Description("獲取記錄總頁數"), DefaultValue(0), Category("分頁")] 62 public int PageCount 63 { 64 get 65 { 66 return this.m_PageCount; 67 } 68 } 69 70 [Description("設置或獲取記錄總數"), Category("分頁")] 71 public int RecordCount 72 { 73 set 74 { 75 this._recordCount = value; 76 } 77 get 78 { 79 return this._recordCount; 80 } 81 } 82 83 [Description("當前的頁面索引, 開始爲1"), DefaultValue(0), Category("分頁")] 84 [Browsable(false)] 85 public int PageIndex 86 { 87 set 88 { 89 this._pageIndex = value; 90 } 91 get 92 { 93 return this._pageIndex; 94 } 95 } 96 97 /// 98 /// 初始化分頁信息 99 /// 每頁記錄數 100 /// 總記錄數 101 /// 102 public void InitPageInfo(int recordCount, int pageSize) 103 { 104 this._recordCount = recordCount; 105 this._pageSize = pageSize; 106 this.InitPageInfo(); 107 } 108 109 /// 110 /// 初始化分頁信息 111 /// 總記錄數 112 /// 113 public void InitPageInfo(int recordCount) 114 { 115 this._recordCount = recordCount; 116 this.InitPageInfo(); 117 } 118 /// 119 /// 初始化分頁信息 120 /// 121 public void InitPageInfo() 122 { 123 if (this._pageSize < 1) 124 this._pageSize = 10; //如果每頁記錄數不正確,即更改爲10 125 if (this._recordCount < 0) 126 this._recordCount = 0; //如果記錄總數不正確,即更改爲0 127 128 //取得總頁數 129 if (this._recordCount % this._pageSize == 0) 130 { 131 this.m_PageCount = this._recordCount / this._pageSize; 132 } 133 else 134 { 135 this.m_PageCount = this._recordCount / this._pageSize + 1; 136 } 137 138 //設置當前頁 139 if (this._pageIndex > this.m_PageCount) 140 { 141 this._pageIndex = this.m_PageCount; 142 } 143 if (this._pageIndex < 1) 144 { 145 this._pageIndex = 1; 146 } 147 148 //設置上一頁按鈕的可用性 149 bool enable = (this.PageIndex > 1); 150 this.btnPrevious.Enabled = enable; 151 152 //設置首頁按鈕的可用性 153 enable = (this.PageIndex > 1); 154 this.btnFirst.Enabled = enable; 155 156 //設置下一頁按鈕的可用性 157 enable = (this.PageIndex < this.PageCount); 158 this.btnNext.Enabled = enable; 159 160 //設置末頁按鈕的可用性 161 enable = (this.PageIndex < this.PageCount); 162 this.btnLast.Enabled = enable; 163 this.txtPageIndex.Text = this._pageIndex.ToString(); 164 this.lblPageInfo.Text = string.Format("共 {0} 條記錄,每頁 {1} 條,共 {2} 頁", this._recordCount, this._pageSize, this.m_PageCount); 165 } 166 167 public void RefreshData(int page) 168 { 169 this._pageIndex = page; 170 EventArgs e = new EventArgs(); 171 OnPageChanged(e); 172 } 173 174 private void btnFirst_Click(object sender, System.EventArgs e) 175 { 176 this.RefreshData(1); 177 } 178 179 private void btnPrevious_Click(object sender, System.EventArgs e) 180 { 181 if (this._pageIndex > 1) 182 { 183 this.RefreshData(this._pageIndex - 1); 184 } 185 else 186 { 187 this.RefreshData(1); 188 } 189 } 190 private void btnNext_Click(object sender, System.EventArgs e) 191 { 192 if (this._pageIndex < this.m_PageCount) 193 { 194 this.RefreshData(this._pageIndex + 1); 195 } 196 else if (this.m_PageCount < 1) 197 { 198 this.RefreshData(1); 199 } 200 else 201 { 202 this.RefreshData(this.m_PageCount); 203 } 204 } 205 206 private void btnLast_Click(object sender, System.EventArgs e) 207 { 208 this.RefreshData(this.m_PageCount > 0 ? this.m_PageCount : 1); 209 } 210 211 private void txtPageIndex_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e) 212 { 213 if (e.KeyCode == Keys.Enter) 214 { 215 int num; 216 try 217 { 218 num = Convert.ToInt16(this.txtPageIndex.Text); 219 } 220 catch 221 { 222 num = 1; 223 } 224 225 if (num > this.m_PageCount) 226 num = this.m_PageCount; 227 if (num < 1) 228 num = 1; 229 230 this.RefreshData(num); 231 } 232 } 233 } 234 }
代碼基本沒有什麼難度,相信大家都能看得懂,那麼如何使用這個控件呢?
首先在生成的工具箱中拖動這個分頁控件到界面上,再後再做數據綁定的代碼即可。我直接展示一個已經做成的界面,如下圖所示:
上面就是分頁的效果,如何實現的呢?下面給出實現代碼。
我們可以在Load事件中調用下面的Search()方法對數據進行綁定,如下代碼所示:
1 private void Search() 2 { 3 var recordCount = 0; 4 this.DTProductInfo = GetData(out recordCount, ucPager.PageIndex, ucPager.PageSize, this.searchValue); 5 ucPager.RecordCount = recordCount; 6 ucPager.InitPageInfo(); 7 // 加載綁定數據 8 this.GetList(); 9 } 10 11 private DataTable GetData(out int recordCount, int pageIndex, int pageSize,string search) 12 { 13 return new ProductInfoManager(dbProvider).GetDTByPage(out recordCount, pageIndex, pageSize, search,ProductInfoTable.FieldCreateOn + " DESC "); 14 } 15 16 public override void GetList() 17 { 18 this.dgvProductInfo.AutoGenerateColumns = false; 19 if (this.DTProductInfo.Columns.Count > 0) 20 { 21 this.DTProductInfo.DefaultView.Sort = ProductInfoTable.FieldCreateOn; 22 } 23 24 this.dgvProductInfo.DataSource = this.DTProductInfo.DefaultView; 25 this.SetControlState(); 26 }
同時需要對UcPagerEx的PageChanged事件做處理,以啓用用戶分頁的需求,代碼如下:
1 private void ucPager_PageChanged(object sender, EventArgs e) 2 { 3 var holdCursor = this.Cursor; 4 this.Cursor = Cursors.WaitCursor; 5 Search(); 6 this.Cursor = holdCursor; 7 }
附註:對於上面的“GetDTByPage”方法可以任意實現,可以調用存儲過程,也可以使用代碼進行分頁。只要返回分頁的數據即可。
下面給出一些分頁的效果,如下圖所示: