一个精简的分页类,配合现有的界面按钮使用:

分页类(Pagination.cs)
csharp
using System;
using System.Collections.Generic;
/// <summary>
/// 分页管理类
/// </summary>
public class Pagination
{
private int _pageIndex = 1; // 当前页码
private int _pageSize = 10; // 每页显示条数
private int _totalCount = 0; // 总记录数
private int _totalPages = 0; // 总页数
/// <summary>
/// 页码改变事件(在UI中订阅此事件来刷新数据)
/// </summary>
public event Action OnPageChanged;
/// <summary>
/// 当前页码(从1开始)
/// </summary>
public int PageIndex
{
get { return _pageIndex; }
set
{
if (value >= 1 && value <= _totalPages)
{
_pageIndex = value;
OnPageChanged?.Invoke();
}
}
}
/// <summary>
/// 每页显示条数
/// </summary>
public int PageSize
{
get { return _pageSize; }
set
{
if (value > 0)
{
_pageSize = value;
// 改变每页条数后重置到第一页
_pageIndex = 1;
// 重新计算总页数
RecalculateTotalPages();
OnPageChanged?.Invoke();
}
}
}
/// <summary>
/// 总记录数
/// </summary>
public int TotalCount
{
get { return _totalCount; }
set
{
_totalCount = value;
RecalculateTotalPages();
}
}
/// <summary>
/// 总页数
/// </summary>
public int TotalPages => _totalPages;
/// <summary>
/// 是否有上一页
/// </summary>
public bool HasPrevPage => _pageIndex > 1;
/// <summary>
/// 是否有下一页
/// </summary>
public bool HasNextPage => _pageIndex < _totalPages;
/// <summary>
/// 数据起始索引(用于SQL查询的 OFFSET,从0开始)
/// </summary>
public int StartIndex => (_pageIndex - 1) * _pageSize;
/// <summary>
/// 重新计算总页数
/// </summary>
private void RecalculateTotalPages()
{
if (_totalCount == 0)
{
_totalPages = 1;
}
else
{
_totalPages = (int)Math.Ceiling((double)_totalCount / _pageSize);
}
// 如果当前页超出总页数,调整到最后一页
if (_pageIndex > _totalPages)
{
_pageIndex = _totalPages;
}
}
/// <summary>
/// 上一页
/// </summary>
public void PrevPage()
{
if (HasPrevPage)
{
PageIndex--;
}
}
/// <summary>
/// 下一页
/// </summary>
public void NextPage()
{
if (HasNextPage)
{
PageIndex++;
}
}
/// <summary>
/// 跳转到指定页
/// </summary>
/// <param name="pageNumber">页码(从1开始)</param>
/// <returns>是否跳转成功</returns>
public bool GoToPage(int pageNumber)
{
if (pageNumber >= 1 && pageNumber <= _totalPages)
{
PageIndex = pageNumber;
return true;
}
return false;
}
/// <summary>
/// 获取分页信息文本(用于显示在界面上)
/// </summary>
public string GetPageInfoText()
{
return $"第 {_pageIndex} / {_totalPages} 页,共 {_totalCount} 条记录";
}
/// <summary>
/// 获取按钮状态(用于界面按钮的Enabled属性)
/// </summary>
public (bool canPrev, bool canNext) GetButtonStatus()
{
return (HasPrevPage, HasNextPage);
}
}
使用示例(在窗体中)
csharp
public partial class MainForm : Form
{
private Pagination _pagination;
private DataTable _allData; // 全部数据
public MainForm()
{
InitializeComponent();
InitPagination();
LoadMockData();
LoadPageData();
}
private void InitPagination()
{
_pagination = new Pagination();
_pagination.PageSize = 10; // 设置每页条数
_pagination.OnPageChanged += () =>
{
// 页码改变时重新加载数据
LoadPageData();
UpdateUI();
};
}
private void UpdateUI()
{
// 更新按钮状态
var (canPrev, canNext) = _pagination.GetButtonStatus();
btnPrev.Enabled = canPrev;
btnNext.Enabled = canNext;
// 更新显示信息
lblPageInfo.Text = _pagination.GetPageInfoText();
}
// 按钮事件
private void btnPrev_Click(object sender, EventArgs e)
{
_pagination.PrevPage();
}
private void btnNext_Click(object sender, EventArgs e)
{
_pagination.NextPage();
}
// 跳转按钮
private void btnJump_Click(object sender, EventArgs e)
{
if (int.TryParse(txtJumpPage.Text, out int page))
{
if (!_pagination.GoToPage(page))
{
MessageBox.Show($"页码范围:1-{_pagination.TotalPages}");
}
}
else
{
MessageBox.Show("请输入有效的页码");
}
}
// 设置每页条数
private void cmbPageSize_SelectedIndexChanged(object sender, EventArgs e)
{
if (cmbPageSize.SelectedItem != null)
{
int pageSize = Convert.ToInt32(cmbPageSize.SelectedItem);
_pagination.PageSize = pageSize;
}
}
// 加载分页数据
private void LoadPageData()
{
// 方法1:从内存数据中取
var pageData = _allData.Rows
.Cast<DataRow>()
.Skip(_pagination.StartIndex)
.Take(_pagination.PageSize)
.CopyToDataTable();
dataGridView1.DataSource = pageData;
// 方法2:从数据库查询(推荐)
// string sql = @"
// SELECT * FROM Users
// ORDER BY ID
// OFFSET @Offset ROWS
// FETCH NEXT @PageSize ROWS ONLY";
//
// var parameters = new
// {
// Offset = _pagination.StartIndex,
// PageSize = _pagination.PageSize
// };
// dataGridView1.DataSource = ExecuteQuery(sql, parameters);
}
private void LoadMockData()
{
// 模拟155条数据
_allData = new DataTable();
_allData.Columns.Add("ID", typeof(int));
_allData.Columns.Add("Name", typeof(string));
for (int i = 1; i <= 155; i++)
{
_allData.Rows.Add(i, $"用户{i}");
}
// 设置总记录数
_pagination.TotalCount = _allData.Rows.Count;
}
}
核心属性说明
| 属性 | 说明 |
|---|---|
PageIndex |
当前页码(从1开始) |
PageSize |
每页条数 |
TotalCount |
总记录数(外部赋值) |
TotalPages |
总页数(自动计算) |
HasPrevPage |
是否有上一页 |
HasNextPage |
是否有下一页 |
StartIndex |
数据起始索引(从0开始,用于SQL的OFFSET) |
使用步骤
- 实例化分页类 :
_pagination = new Pagination(); - 订阅事件 :
_pagination.OnPageChanged += LoadData; - 设置总记录数 :
_pagination.TotalCount = totalRows; - 按钮事件调用 :
_pagination.PrevPage()/NextPage()/GoToPage() - 获取数据 :使用
StartIndex和PageSize查询数据库 - 更新UI :根据
HasPrevPage/HasNextPage控制按钮启用状态
这个分页类不包含任何UI控件,完全独立,你只需要在窗体的按钮事件中调用对应方法即可。