LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

【C#】DataGridView 中实现分页功能

admin
2026年1月18日 21:9 本文热度 60

在 DataGridView 中实现分页功能,这是处理大量数据时的常用需求,能避免表格加载过慢、提升用户操作体验。核心思路是基于全局原始数据源,通过「页码 + 每页显示条数」截取对应数据片段作为当前页数据,再绑定到 DataGridView 展示,同时配套分页控件实现页码切换、页数统计等功能。下面基于之前的 Student 实体和全局数据源,完整实现分页功能。

一、前置准备

 1. 保留全局原始数据源与通用绑定方法



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

// 全局学生集合(原始完整数据源,分页仅截取片段,不修改原始数据)
private List<Student> _studentGlobalList = new List<Student>()
{
    new Student(){ Id=1, Name="张三", Age=18, ClassName="高一(1)班"},
    new Student(){ Id=2, Name="李四", Age=17, ClassName="高一(2)班"},
    new Student(){ Id=3, Name="王五", Age=18, ClassName="高一(1)班"},
    new Student(){ Id=4, Name="张小三", Age=19, ClassName="高一(1)班"},
    new Student(){ Id=5, Name="李小四", Age=17, ClassName="高一(2)班"},
    new Student(){ Id=6, Name="赵五", Age=18, ClassName="高一(3)班"},
    new Student(){ Id=7, Name="钱六", Age=19, ClassName="高一(3)班"},
    new Student(){ Id=8, Name="孙七", Age=17, ClassName="高一(1)班"},
    new Student(){ Id=9, Name="周八", Age=18, ClassName="高一(2)班"},
    new Student(){ Id=10, Name="吴九", Age=19, ClassName="高一(3)班"}
};

// 通用数据绑定方法,接收分页结果集并绑定到 DataGridView
private void BindDataToDgv(List<Student> dataList)
{
    dgvStudent.DataSource = null; // 清空原有绑定,避免数据残留
    dgvStudent.DataSource = dataList;
    // 优化表头显示
    dgvStudent.Columns["Id"].HeaderText = "学生ID";
    dgvStudent.Columns["Name"].HeaderText = "学生姓名";
    dgvStudent.Columns["Age"].HeaderText = "年龄";
    dgvStudent.Columns["ClassName"].HeaderText = "所在班级";
}



 2. 定义分页核心变量(全局)
用于记录分页状态,确保页码切换时数据一致性:



1
2
3

private int _currentPage = 1; // 当前页码(默认第1页)
private int _pageSize = 3; // 每页显示条数(默认每页3条,可自定义)
private int _totalPages; // 总页数(根据原始数据总数和每页条数计算)



3. 窗体分页控件布局
添加以下控件实现分页交互(均命名便于代码调用):

  • • 2 个 Button 控件:btnFirstPage(首页)、btnPrevPage(上一页)、btnNextPage(下一页)、btnLastPage(末页)(实际需 4 个按钮,覆盖完整分页操作)
  • • 2 个 Label 控件:lblPageInfo(显示分页统计信息,如「当前第 1 页 / 共 4 页」)
  • • 可选:NumericUpDown 控件(自定义每页显示条数)

二、分页核心原理与实现

1. 核心原理:LINQ 截取分页数据片段
分页的核心是通过 LINQ 的 Skip() 和 Take() 方法配合,从原始数据源中截取当前页对应的数据集:

  • • Skip(n):跳过前 n 条数据(n = (当前页码-1) * 每页显示条数),定位到当前页的起始位置。
  • • Take(m):从起始位置开始,获取 m 条数据(m = 每页显示条数),即当前页的展示数据。
  • • 先计算总页数:总页数 = 向上取整(原始数据总数 / 每页显示条数),避免出现无数据的空页。
    2. 分页数据加载核心方法(封装,方便重复调用)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

private void LoadPageData()
{
    // 1. 计算总页数(向上取整,避免余数数据无法展示)
    int totalCount = _studentGlobalList.Count;
    _totalPages = (int)Math.Ceiling((double)totalCount / _pageSize);

    // 2. 边界验证:确保当前页码在有效范围内(避免页码越界)
    if (_currentPage < 1) _currentPage = 1;
    if (_currentPage > _totalPages && _totalPages > 0) _currentPage = _totalPages;

    // 3. 核心:使用 LINQ Skip() + Take() 截取当前页数据
    var currentPageData = _studentGlobalList
        .Skip( (_currentPage - 1) * _pageSize ) // 跳过前 (当前页-1)*每页条数 条数据
        .Take(_pageSize) // 获取当前页的 n 条数据
        .ToList(); // 转为 List<Student>,方便绑定到 DataGridView

    // 4. 绑定当前页数据,刷新表格展示
    BindDataToDgv(currentPageData);

    // 5. 更新分页统计信息,展示给用户
    UpdatePageInfoLabel();
}

// 封装:更新分页信息标签
private void UpdatePageInfoLabel()
{
    int totalCount = _studentGlobalList.Count;
    lblPageInfo.Text = $"当前第 {_currentPage} 页 / 共 {_totalPages} 页 | 总数据 {totalCount} 条 | 每页 {_pageSize} 条";
}



3. 分页按钮点击事件实现(完整分页操作)
实现「首页、上一页、下一页、末页」的切换逻辑,核心是修改 _currentPage 并调用 LoadPageData() 刷新数据:



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

// 1. 首页
private void btnFirstPage_Click(object sender, EventArgs e)
{
    _currentPage = 1; // 重置为第1页
    LoadPageData();
}

// 2. 上一页
private void btnPrevPage_Click(object sender, EventArgs e)
{
    if (_currentPage > 1) // 边界验证:不是第1页才允许上移
    {
        _currentPage--;
        LoadPageData();
    }
    else
    {
        MessageBox.Show("当前已是首页,无法继续上一页!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
    }
}

// 3. 下一页
private void btnNextPage_Click(object sender, EventArgs e)
{
    if (_currentPage < _totalPages) // 边界验证:不是最后一页才允许下移
    {
        _currentPage++;
        LoadPageData();
    }
    else
    {
        MessageBox.Show("当前已是末页,无法继续下一页!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
    }
}

// 4. 末页
private void btnLastPage_Click(object sender, EventArgs e)
{
    _currentPage = _totalPages; // 直接跳转到总页数
    LoadPageData();
}



4. 初始化分页(窗体加载时)



1
2
3
4
5
6
7
8
9
10

private void Form1_Load(object sender, EventArgs e)
{
    // 配置 DataGridView 基础属性
    dgvStudent.AllowUserToAddRows = false;
    dgvStudent.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
    dgvStudent.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
 
    // 初始化加载第1页数据
    LoadPageData();
}



三、关键知识点说明

1、LINQ Skip() 与 Take() 的核心作用:
这两个方法是实现内存分页的关键,仅对原始数据源进行「查询截取」,不修改原始数据,保证分页操作可重复、无数据丢失。注意:Skip() 和 Take() 仅支持 IEnumerable 类型,需确保数据源为泛型集合(如 List)。
2、总页数的正确计算(向上取整):
由于 int 类型除法会向下取整(如 10/3=3),而实际需要 4 页才能展示全部数据,因此必须将其中一个操作数转为 double 后,使用 Math.Ceiling() 进行向上取整,公式:



1

_totalPages = (int)Math.Ceiling((double)_studentGlobalList.Count / _pageSize);



若原始数据总数为 0,需额外处理(避免 _totalPages 为 0 导致异常)。
3、页码边界验证的必要性:
分页操作中必须对 _currentPage 进行边界限制(≥1 且 ≤_totalPages),避免用户异常操作(如手动修改页码、数据删除后总页数减少)导致 Skip() 方法传入负数或超出数据总数的参数,引发索引越界异常。
4、分页与筛选的结合(扩展):
若需要实现「筛选后分页」,只需先对 _studentGlobalList 进行筛选,得到筛选结果集,再以筛选结果集为数据源进行分页(修改 LoadPageData() 中的数据源即可),核心分页逻辑不变。
5、自定义每页显示条数(优化):
可通过 NumericUpDown 控件让用户自定义 _pageSize,修改后重置 _currentPage = 1 并调用 LoadPageData() 即可刷新分页:



1
2
3
4
5
6

private void numPageSize_ValueChanged(object sender, EventArgs e)
{
    _pageSize = (int)numPageSize.Value;
    _currentPage = 1; // 每页条数变化,重置为第1页
    LoadPageData();
}



四、使用须知

  • • 1、确保窗体上已添加对应的分页按钮(4 个)和分页信息标签,并绑定相应的点击事件。
  • • 2、依赖之前定义的 Student 实体、全局数据源和 BindDataToDgv 绑定方法,无需额外修改已有代码。
  • • 3、运行后,表格将展示第 1 页(3 条数据),点击分页按钮可切换页码,边界情况会给出友好提示,分页信息标签实时更新统计数据。

五、总结

  • • 分页功能的核心:LINQ Skip() + Take() 截取数据片段 + 分页状态变量记录 + 重新绑定 DataGridView。
  • • 关键步骤:计算总页数 → 边界验证页码 → 截取当前页数据 → 绑定展示 → 更新分页信息。
  • • 核心注意点:总页数向上取整、页码边界验证、保留原始数据源不修改,确保分页稳定性和可扩展性。
  • • 扩展方向:支持自定义每页条数、筛选后分页、页码输入跳转,满足复杂业务场景需求。


阅读原文:原文链接


该文章在 2026/1/19 10:37:59 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2026 ClickSun All Rights Reserved