C#--資料報表分頁的實現彙總
阿新 • • 發佈:2020-11-15
以下是學習筆記:
效果如下:
通用分頁的設計與實現
一、分頁資料查詢的原理分析
二、分頁類的設計分析
總原則:提取不變的,封裝變化的;不變的作為方法體,變化的作為引數
【變化的】
1.每頁顯示的條數
2.顯示的欄位(屬性)
3.表的名稱
4.查詢條件
5.過濾的條件(主鍵或唯一鍵)
6.過濾的條數==================(需要計算的)
7.當前顯示的頁碼
8.排序條件
9.記錄總數===================(查詢的結果返回)
10.顯示的總頁數================(查詢結果返回後進一步運算得到)
【不變的】
查詢語句的核心結構
【編寫分頁查詢方法】
該查詢方法不需要直接的引數傳遞,引數獲取全部通過屬性。
一、分頁資料查詢的原理分析
use DataPagerDB go --查詢第一頁 select Top 5 StudentId,StudentName,Gender,Birthday,PhoneNumber from Students where Birthday>'1989/10/12' --查詢第二頁 select Top 5 StudentId,StudentName,Gender,Birthday,PhoneNumber from Students where Birthday>'1989/10/12' and StudentId not in--不在下面的這個範圍內的 (select Top 5 StudentId from Students where Birthday>'1989/10/12' order by StudentId ASC ) order by StudentId ASC --查詢第三頁 總結過濾條數=每頁顯示的條數*(顯示的第幾頁-1) select Top 5 StudentId,StudentName,Gender,Birthday,PhoneNumber from Students where Birthday>'1989/10/12' and StudentId not in (select Top 10 StudentId from Students where Birthday>'1989/10/12' order by StudentId ASC ) order by StudentId ASC --查詢符合條件的記錄總數 select COUNT(*) from Students where Birthday>'1989/10/12' --計算符合條件的總頁數(比如總計5條,每頁分別顯示:3、5、8,計算實際分頁數) print '----相除----' print 5/3 --2頁 print 5/5 --1頁 print 5/8 --1頁 print '---實際分頁數---' print 5/3+1 --2頁 print 5/5 --1頁 print 5/8+1 --1頁 --對於除不盡的情況,通過取模來判斷(有餘數的都加1,就是實際頁數) print '---取模---' print 5%3 print 5%5 print 5%8 --==============分頁實現的基本思路================= --每頁顯示的條數 --過濾掉的總數=每頁顯示的條數*(當前顯示的頁數-1) --查詢條件的確定 --排序條件 --獲取滿足條件的記錄總數 --知道查詢結果需要顯示的頁數=記錄總數/每頁顯示條數 + 1(如果記錄總數和每頁顯示條數取模後不為0,則加1)
二,分頁類的設計
提取不變的,封裝變化的;不變的作為方法體,變化的作為引數
分頁類的程式碼:SqlDataPager,實際開發應該放在DAL資料訪問類庫中的
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Data; namespace CSDataPager { /// <summary> /// 通用資料分頁類 /// </summary> public class SqlDataPager { #region 一般屬性 /// <summary> /// 每頁顯示的條數 /// </summary> public int PageSize { get; set; } /// <summary> /// 需要顯示的欄位(以逗號分隔 ) /// </summary> public string FiledName { get; set; } /// <summary> /// 表的名稱 /// </summary> public string TableName { get; set; } /// <summary> /// 查詢條件 /// </summary> public string Condition { get; set; } /// <summary> /// 表的主鍵或唯一鍵 /// </summary> public string PrimaryKey { get; set; } /// <summary> /// 當前頁碼 /// </summary> public int CurrentPage { get; set; } /// <summary> /// 排序條件 /// </summary> public string Sort { get; set; } #endregion #region 只讀屬性 /// <summary> /// 記錄的總數【不能直接賦值】 /// </summary> // public int RecordCount { get; set; }//此中手設計不安全 private int recordCount; public int RecordCount//設定只讀屬性,外面不能直接賦值 { get { return recordCount; } } /// <summary> /// 總頁數 /// </summary> public int TotalPages { get { if (recordCount != 0)//如果查詢記錄總數不為0 { if (recordCount % PageSize != 0) { return recordCount / PageSize + 1; } else { return recordCount / PageSize; } } else { this.CurrentPage = 1;//如果查詢沒有資料,則當前頁碼需要復位 return 0; } } } #endregion //分頁查詢方法所用的SQL語句 private string GetPagedSQL() { //計算需要過濾的總數 string filterCount = (PageSize * (CurrentPage - 1)).ToString(); //組合SQL語句 string sql = "select Top {0} {1} from {2} where {3} and {4} not in ";//0:每頁顯示的條數,1:欄位,2:表名,3:where條件,, sql += "(select Top {5} {6} from {7} where {8} order by {9} ) order by {10};";//5:過濾的條數,6:主鍵,7:表名,8:where條件,9:排序的條件,10:排序的條件 sql += "select count(*) from {11} where {12}";//11:表名,12:where條件 查詢滿足條件的總數 sql = string.Format(sql, PageSize, FiledName, TableName, Condition, PrimaryKey, filterCount, PrimaryKey, TableName, Condition, Sort, Sort, TableName, Condition); return sql; } /// <summary> /// 執行分頁查詢,返回DataTable /// </summary> /// <returns></returns> public DataTable GetPagedData() { //【1】執行查詢,返回分頁後的結果集 DataSet ds = SQLHelper.GetDataSet(GetPagedSQL()); //【2】獲取滿足記錄的總數 this.recordCount = Convert.ToInt32(ds.Tables[1].Rows[0][0]);//ds的第二張表的,第一行的,第一列 return ds.Tables[0]; } } }
三,分頁UI的實現
public partial class FrmDataPager : Form { private SqlDataPager objPager = null; public FrmDataPager()//需要初始化的內容,要放在窗體的建構函式中 { InitializeComponent(); this.dtpBirthday.Text = "1988-1-1"; //初始化資料分頁物件 objPager = new SqlDataPager() { PrimaryKey = "StudentId",//表的主鍵 TableName = "Students", FiledName = "StudentId,StudentName,Gender,Birthday,PhoneNumber", CurrentPage = 1, Sort = "StudentId ASC"//排序條件 }; //設定預設的顯示條數 this.cboRecordList.SelectedIndex = 1; this.dgvStudentList.AutoGenerateColumns = false;//DataGridView自動生成列為禁止 //禁用相關按鈕 this.btnFirst.Enabled = false; this.btnNext.Enabled = false; this.btnPre.Enabled = false; this.btnLast.Enabled = false; this.btnToPage.Enabled = false; } //執行查詢的公共方法 private void Query() { //開啟所有按鈕 this.btnFirst.Enabled = true; this.btnNext.Enabled = true; this.btnPre.Enabled = true; this.btnLast.Enabled = true; this.btnToPage.Enabled = true; //【1】設定分頁查詢的條件 objPager.Condition = string.Format("Birthday>'{0}'", this.dtpBirthday.Text); //【2】設定每頁顯示的條數 objPager.PageSize = Convert.ToInt32(this.cboRecordList.Text.Trim()); //【3】執行查詢 this.dgvStudentList.DataSource = objPager.GetPagedData(); //【4】顯示記錄總數、顯示總頁數、顯示當前頁碼 this.lblRecordsCount.Text =objPager.RecordCount.ToString ();//總數 this.lblPageCount.Text = objPager.TotalPages.ToString();//總頁數 if (this.lblPageCount.Text == "0")//如果總頁數為0 { this.lblCurrentPage.Text = "0"; } else { this.lblCurrentPage.Text = objPager.CurrentPage.ToString();//當前頁 } //禁用按鈕的情況 if (this.lblPageCount.Text == "0" || this.lblPageCount.Text == "1") { this.btnFirst.Enabled = false; this.btnNext.Enabled = false; this.btnPre.Enabled = false; this.btnLast.Enabled = false; this.btnToPage.Enabled = false; } else { this.btnToPage.Enabled = true; } } //提交查詢 private void btnQuery_Click(object sender, EventArgs e) { objPager.CurrentPage = 1;//每次執行查詢都要設定為第1頁 Query(); this.btnPre.Enabled = false;//上一頁按鈕 this.btnFirst.Enabled = false;//第一頁按鈕 } //第1頁 private void btnFirst_Click(object sender, EventArgs e) { objPager.CurrentPage = 1; Query(); this.btnPre.Enabled = false; this.btnFirst.Enabled = false; // btnQuery_Click(null, null);//上面4行不寫,可以直接呼叫上面的事件也是一樣的 } //下一頁 private void btnNext_Click(object sender, EventArgs e) { objPager.CurrentPage += 1; Query(); //當執行到最後一頁的時候應該禁用最後一頁和下一頁的按鈕 if (objPager.CurrentPage == objPager.TotalPages) { this.btnNext.Enabled = false; this.btnLast.Enabled = false; } } //上一頁 private void btnPre_Click(object sender, EventArgs e) { objPager.CurrentPage -= 1; Query(); if (objPager.CurrentPage == 1)//如果是第一頁 { this.btnPre.Enabled = false; this.btnFirst.Enabled = false; } } //最後一頁 private void btnLast_Click(object sender, EventArgs e) { objPager.CurrentPage = objPager.TotalPages; Query(); this.btnNext.Enabled = false; this.btnLast.Enabled = false; } //跳轉到 private void btnToPage_Click(object sender, EventArgs e) { if (this.txtToPage.Text.Trim().Length == 0)//如果沒有輸入 { MessageBox.Show("請輸入要跳轉的頁碼!","資訊提示"); this.txtToPage.Focus(); return; } //使用正則表示式驗證必須為大於0的正整數... int toPage = Convert.ToInt32(this.txtToPage.Text.Trim()); if (toPage > objPager.TotalPages) { MessageBox.Show("跳轉的頁數不能大於資料總頁數!","資訊提示"); this.txtToPage.Focus(); this.txtToPage.SelectAll();//讓使用者的輸入內容全部選中,使用者可以直接改啦 return; } //開始跳轉頁數 objPager.CurrentPage = toPage; Query(); if (objPager.CurrentPage == 1) { this.btnPre.Enabled = false; this.btnFirst.Enabled = false; } else if (objPager.CurrentPage == objPager.TotalPages) { this.btnNext.Enabled = false; this.btnLast.Enabled = false; } } //關閉視窗 private void btnClose_Click(object sender, EventArgs e) { this.Close(); } }