1. 程式人生 > 實用技巧 >C#--資料報表分頁的實現彙總

C#--資料報表分頁的實現彙總

以下是學習筆記:

效果如下:


通用分頁的設計與實現

一、分頁資料查詢的原理分析

二、分頁類的設計分析

總原則:提取不變的,封裝變化的;不變的作為方法體,變化的作為引數

【變化的】
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();
        }
    }