winform下的一个分页控件总结
前言:刚刚整理完这篇,觉得有必要把自己在开发win form程序的时候经常用到的一个分页程序也总结出来。虽然自己已经用得纯熟了,但是怕自己介绍的不好,别人不一定知道到底该怎么用,所以本文也准备了一个demo,在本文最后您可以下载试用。
1、工程和项目结构
本文示例主要就是通过IBatisNet进行一个简单的数据查询。
2、分页控件
(1)、分页效果图
在DotNet.Common下的DotNet.Common.WinForm工程下有一个用户控件PagerControl,它的设计视图主要包括四个LinkLabel、一个数字文本框、一个Button控件以及几个和显示统计数字相关的Label控件。本文示例的一个分页显示效果如下:
控件比较丑陋,是多么没有美术和设计天赋啊。
(2)、控件使用方式
1 2 3 4 | //绑定页码相关信息 PagerControl pager = new PagerControl( this .CurrentPage, this .RecordsPerPage, this .TotalCount, "跳转" ); pager.currentPageChanged += new EventHandler(pager_currentPageChanged); //页码变化 触发的事件 this .panelPager.Controls.Add(pager); //在Panel容器中加入这个控件 |
使用这个控件的时候,只需要简单的new一个控件对象,然后传入正确的参数,如当前页面,每页记录数,数据集合总记录数以及按钮上显示的文字即可。
(3)、如何正确传参和分页
对于分页来说,重要的是传入查询条件和页码参数。查询条件我们的MainForm窗体有现成的输入文本框,那么如何传递当前页码参数呢?毫无疑问,4个LinkLabel以及一个数字输入框和一个按钮组合会引发当前页数字的改变,所以我们要在它们所对应的一些事件下做一些CurrentPage的处理:
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 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | #region 相关控件事件 private void lnkFirst_LinkClicked( object sender, LinkLabelLinkClickedEventArgs e) { CurrentPage = 1; DrawControl(); } private void lnkPrev_LinkClicked( object sender, LinkLabelLinkClickedEventArgs e) { CurrentPage = Math.Max(1, CurrentPage - 1); DrawControl(); } private void lnkNext_LinkClicked( object sender, LinkLabelLinkClickedEventArgs e) { CurrentPage = Math.Min(PageCount, CurrentPage + 1); DrawControl(); } private void lnkLast_LinkClicked( object sender, LinkLabelLinkClickedEventArgs e) { CurrentPage = PageCount; DrawControl(); } /// <summary> /// enter键功能 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void txtPageNum_KeyPress( object sender, KeyPressEventArgs e) { string strNum = this .txtPageNum.Text.Trim(); if (e.KeyChar == ( char )Keys.Enter && RegUtil.IsPositiveNumber(strNum)) { CurrentPage = int .Parse(strNum); DrawControl(); } } /// <summary> /// 页数限制 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void txtPageNum_TextChanged( object sender, EventArgs e) { string strNum = this .txtPageNum.Text.Trim(); if (strNum.Length > 0 && RegUtil.IsPositiveNumber(strNum) && int .Parse(strNum) > PageCount) { txtPageNum.Text = PageCount.ToString(); } } /// <summary> /// 跳转 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnGo_Click( object sender, EventArgs e) { string strNum = this .txtPageNum.Text.Trim(); if (RegUtil.IsPositiveNumber(strNum) == false ) { return ; } CurrentPage = int .Parse(strNum); DrawControl(); } #endregion |
我们注意到DrawControl方法,这是非常重要的一个函数:
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 | /// <summary> /// 页面控件呈现 /// </summary> private void DrawControl() { this .btnGo.Text = this .JumpText; this .lblCurrentPage.Text = CurrentPage.ToString(); this .lblPageCount.Text = PageCount.ToString(); this .lblTotalCount.Text = TotalCount.ToString(); this .lblRecPerPg.Text = RecordsPerPage.ToString(); if (currentPageChanged != null ) { currentPageChanged( this , null ); //当前分页数字改变时,触发委托事件 } SetFormCtrEnabled(); if (PageCount == 1) //有且仅有一页 { this .lnkFirst.Enabled = false ; this .lnkPrev.Enabled = false ; this .lnkNext.Enabled = false ; this .lnkLast.Enabled = false ; this .btnGo.Enabled = false ; } else if (CurrentPage == 1) //第一页 { this .lnkFirst.Enabled = false ; this .lnkPrev.Enabled = false ; //this.lnkFirst.ForeColor = Color.Gray; //this.lnkPrev.ForeColor = Color.Gray; } else if (CurrentPage == this .PageCount) //最后一页 { this .lnkNext.Enabled = false ; this .lnkLast.Enabled = false ; } } |
因为它会有条件地触发下面的委托事件:
1 | public event EventHandler currentPageChanged; |
我们完全可以这样理解:当我们点击按钮或者LinkLabel的时候,当前页码发生改变,所以需要重新做一些事情比如查询等等。控件就是通过引发currentPageChanged事件来触发的:
1 2 3 4 | if (currentPageChanged != null ) { currentPageChanged( this , null ); //当前分页数字改变时,触发委托事件 } |
至于currentPageChanged委托触发的时候具体要做什么,那是每一个具体窗体中的函数要做的事情。比如本文的demo中,在MainForm中,我们通过定义下面这个方法给pager的currentPageChanged赋值:
1 2 3 4 5 6 7 8 9 | private void pager_currentPageChanged( object sender, EventArgs e) { PagerControl pager = sender as PagerControl; if (pager == null ) { return ; } BindResults(pager.CurrentPage); //查询数据并分页绑定 } |
当分页控件的事件委托触发的时候,这里的BindResults函数通过pager的当前页数进行查询和数据绑定。这样说也许对你通俗地理解委托和事件有好处。
总体来说,实现winform的分页效果比webform要简单一些,因为它不需要考虑某些参数状态的变化。
示例下载:IBatisWinApp
作者:Jeff Wong
出处:http://jeffwongishandsome.cnblogs.com/
本文版权归作者和博客园共有,欢迎围观转载。转载时请您务必在文章明显位置给出原文链接,谢谢您的合作。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
2009-11-21 iBATIS.net复用sql语句片段
2009-11-21 asp.net简单实现禁用或启用页面中的某一类型的控件