随笔 - 268  文章 - 0  评论 - 1028  阅读 - 160万

winform下的一个分页控件总结

前言:刚刚整理完这篇,觉得有必要把自己在开发win form程序的时候经常用到的一个分页程序也总结出来。虽然自己已经用得纯熟了,但是怕自己介绍的不好,别人不一定知道到底该怎么用,所以本文也准备了一个demo,在本文最后您可以下载试用。

 

1、工程和项目结构

IBatisWinProject

本文示例主要就是通过IBatisNet进行一个简单的数据查询。

 

2、分页控件

(1)、分页效果图

在DotNet.Common下的DotNet.Common.WinForm工程下有一个用户控件PagerControl,它的设计视图主要包括四个LinkLabel、一个数字文本框、一个Button控件以及几个和显示统计数字相关的Label控件。本文示例的一个分页显示效果如下:

WinFormPager

控件比较丑陋,是多么没有美术和设计天赋啊。

(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

posted on   JeffWong  阅读(4340)  评论(5编辑  收藏  举报
编辑推荐:
· 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简单实现禁用或启用页面中的某一类型的控件
< 2010年11月 >
31 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 1 2 3 4
5 6 7 8 9 10 11

I know how to make it works and I want to know how it works.
点击右上角即可分享
微信分享提示