分页系列之五:WinForm + DevExpress 自制分页控件
本例的运行环境为:.NET Framework 4.x,DevExpress版本为:18.1.11
添加用户控件,命名为PaginationControl,建议转换为XtraUserControl,不转好像也没什么问题,但既然用了DevExpress,还是转一下为好。
向用户控件中添加BarManager控件,默认会生成3个bar(菜单栏、工具栏和状态栏),删除菜单栏和工具栏,只保留状态栏,然后向状态栏添加控件,效果如下:
上图中,从左到右依次是:
1:BarButtonItem,Name:btnFirst,Caption:第一页,Enabled:false(默认禁用)
2:BarButtonItem,Name:btnPrevious,Caption:上一页,Enabled:false(默认禁用)
3:BarEditItem-TextEdit,Name:txtPage,Caption:输入页码并回车,EditValue:1(初始页码),Mask:MaskType = RegEx, EditMask = '[0-9]*' (只允许输入数字),其他属性:文字居中
4:BarButtonItem,Name:btnNext,Caption:下一页
5:BarButtonItem,Name:btnLast,Caption:最后一页
6:BarEditItem-ComboBoxEdit,Name:cmbPageSize,Caption:每页记录数,EditValue:100,Items:下拉选项,TextEditStyle:DisableTextEditor(只能选择,不能输入,根据情况设置)
7:BarStatictem,Name:lblSummary(类似WinForm的Label,就以lbl为前缀了),Caption:没有加载数据(初始信息)
以上的Caption将显示在控件中,或者在鼠标悬停时显示,分页按钮可以设置相应图标。
PaginationControl.cs代码如下:
using DevExpress.XtraBars; using DevExpress.XtraEditors; using System; using System.ComponentModel; namespace ErpApp { public partial class PaginationControl : XtraUserControl { public PaginationControl() { InitializeComponent(); } private int _pageSize = 100, _page = 1, _totalPage; //每页记录数、当前页码、总页数 private bool _isChangeByUser = true; //是否由用户改变每页记录数或页码,注意何时使用该变量,以及何时赋值 public delegate void LoadDataDelegate(int page); //委托 private LoadDataDelegate _method; //加载数据的方法 /// <summary> /// 每页记录数 /// </summary> [Description("每页记录数"), Category("自定义"), DefaultValue(100)] public int PageSize { get { return _pageSize; } set { _pageSize = value; _isChangeByUser = false; cmbPageSize.EditValue = _pageSize; _isChangeByUser = true; } } /// <summary> /// 加载数据的方法名称 /// </summary> [Description("加载数据的方法名称"), Category("自定义")] public LoadDataDelegate Method { set { _method = value; } } //第一页,btnFirst的ItemClick事件 private void btnFirst_ItemClick(object sender, ItemClickEventArgs e) { _method(1); } //上一页,btnPrevious的ItemClick事件 private void btnPrevious_ItemClick(object sender, ItemClickEventArgs e) { _method(_page - 1); } //下一页,btnNext的ItemClick事件 private void btnNext_ItemClick(object sender, ItemClickEventArgs e) { _method(_page + 1); } //最后一页,btnLast的ItemClick事件 private void btnLast_ItemClick(object sender, ItemClickEventArgs e) { _method(_totalPage); } //页码改变,txtPage的EditValueChanged事件 private void txtPage_EditValueChanged(object sender, EventArgs e) { if (!_isChangeByUser) { return; } if (txtPage.EditValue.ToString() == "") { _method(1); return; } int page = Convert.ToInt32(txtPage.EditValue); if (page < 1) { _method(1); } else if (page > _totalPage) { _method(_totalPage); } else { _method(page); } } //每页记录数改变,cmbPageSize的EditValueChanged事件 private void cmbPageSize_EditValueChanged(object sender, EventArgs e) { if (_isChangeByUser) { _pageSize = Convert.ToInt32(cmbPageSize.EditValue); _method(1); } } /// <summary> /// 设置分页组件内部各控件状态,以及相关文字信息 /// </summary> /// <param name="page">当前页码</param> /// <param name="total">总记录数</param> public void SetPage(int page, int total) { _totalPage = (int)Math.Ceiling((double)total / _pageSize); if (_totalPage <= 1) { btnFirst.Enabled = false; btnPrevious.Enabled = false; btnNext.Enabled = false; btnLast.Enabled = false; txtPage.Enabled = false; } else if (page == 1) { btnFirst.Enabled = false; btnPrevious.Enabled = false; btnNext.Enabled = true; btnLast.Enabled = true; txtPage.Enabled = true; } else if (page == _totalPage) { btnFirst.Enabled = true; btnPrevious.Enabled = true; btnNext.Enabled = false; btnLast.Enabled = false; txtPage.Enabled = true; } else { btnFirst.Enabled = true; btnPrevious.Enabled = true; btnNext.Enabled = true; btnLast.Enabled = true; txtPage.Enabled = true; } _page = page; _isChangeByUser = false; txtPage.EditValue = page; _isChangeByUser = true; if (total == 0) { lblSummary.Caption = "没有记录"; } else { lblSummary.Caption = $"共 {_totalPage:N0} 页 第 {(_pageSize * (page - 1) + 1):N0} 到 {(page == _totalPage ? total : _pageSize * page):N0} 条 共 {total:N0} 条"; } } } }
使用控件,新建一个窗体,从工具箱拖入一个分页控件,必要代码如下:
namespace ErpApp { public partial class TestForm : DevExpress.XtraEditors.XtraForm { public TestForm() { InitializeComponent(); } private void TestForm_Load(object sender, EventArgs e) { paginationControl1.Method = LoadData; LoadData(); //加载第一页 } private void LoadData(int page = 1) { //根据page和paginationControl1.PageSize从数据库获取相应数据,渲染表格等控件 //...... //设置分页组件内部各控件状态,以及相关文字信息,假设获取到的总记录数为9999 paginationControl1.SetPage(page, 9999); } } }
效果如下:
----分页系列----