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();
        }
    }

  

原文地址:https://www.cnblogs.com/baozi789654/p/13974872.html