服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C# - Winform界面中实现通用工具栏按钮的事件处理方法

Winform界面中实现通用工具栏按钮的事件处理方法

2022-02-13 15:19伍华聪 C#

下面小编就为大家分享一篇Winform界面中实现通用工具栏按钮的事件处理方法,具有很好的参考价值,希望对大家有所帮助

在一个给客户做的项目中,界面要求修改增加通用工具栏按钮的事件处理,也就是在主界面中放置几个固定的功能操作按钮,打开不同的页面的时候,实现对应页面的功能处理,这种和我标准的界面处理方式有所不同,标准的列表界面,一般在界面中放置了一些常规的按钮,如查询/更新、新建、编辑、删除、导入、导出等常规操作,现在是需要把这些提升到主界面的层次上放置按钮,这种处理方式也算是提供一种方便吧。本篇随笔介绍实现这个功能的思路和代码实现逻辑。

1、界面功能介绍

这里要实现的通用工具栏按钮的事件处理,具体的界面是这样的,我们处于一个多文档的主界面中,在主界面的顶部工具栏放置这些通用的工具栏按钮,以便提高相关的处理便利和效率。

Winform界面中实现通用工具栏按钮的事件处理方法

从上面的界面我们可以看到,程序主界面的顶部工具栏上有一些常规的操作,包括如查询、新建、编辑、删除、导入、导出等按钮,可以为程序的功能操作提供方便。

当我们打开一个新的窗体页面,那么对应的按钮事件也应该和这个窗体相关,或者我们切换到其他窗体,那么按钮的处理事件也应该跟着变化到对应的窗体上,这种就是我们需要的效果。

上面的逻辑也就是我们新建一个窗体、或者切换一个窗体,那么需要通知顶部工具栏进行更新或者进行一个对接的处理才可以。

2、界面窗体基类的处理

由于我们想尽可能的减少开发的工作量,因此希望在基类进行一些事件或者接口的封装,以便降低新建列表窗体的时候的代码编写。

对于一个如查询操作的处理事件,我们需要定义一个接口来实现这个功能,这样我们才可以在打开的窗体的时候,把它转换为对应的接口处理。

例如我们定义一个imenuaction的接口,以更新事件为例,需要实现三部分的接口,一个是事件定义,一个是判断是否包含更新事件,一个是具体的处理逻辑。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/// <summary>
 /// 定义菜单中的通用按钮事件
 /// </summary>
 public interface imenuaction
 {
  /// <summary>
  /// 更新按钮事件
  /// </summary>
  event eventhandler refresh_menuevent;
 
  /// <summary>
  /// 是否包含更新事件
  /// </summary>
  bool haseventrefresh { get; }
 
  /// <summary>
  /// 更新操作
  /// </summary>
  void processrefresh(object sender, eventargs e);

对于其他总共6个标准的按钮事件处理,我们也同样一样定义,那么整个imenuaction的接口定义如下所示。

?
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
73
74
75
76
77
78
79
80
/// <summary>
 /// 定义菜单中的通用按钮事件
 /// </summary>
 public interface imenuaction
 {
  /// <summary>
  /// 更新按钮事件
  /// </summary>
  event eventhandler refresh_menuevent;
  /// <summary>
  /// 新建按钮事件
  /// </summary>
  event eventhandler add_menuevent;
  /// <summary>
  /// 编辑按钮事件
  /// </summary>
  event eventhandler edit_menuevent;
  /// <summary>
  /// 删除按钮事件
  /// </summary>
  event eventhandler delete_menuevent;
  /// <summary>
  /// 导入按钮事件
  /// </summary>
  event eventhandler import_menuevent;
  /// <summary>
  /// 导出按钮事件
  /// </summary>
  event eventhandler export_menuevent;
 
  /// <summary>
  /// 是否包含更新事件
  /// </summary>
  bool haseventrefresh { get; }
  /// <summary>
  /// 是否包含增加事件
  /// </summary>
  bool haseventadd { get; }
  /// <summary>
  /// 是否包含编辑事件
  /// </summary>
  bool haseventedit { get; }
  /// <summary>
  /// 是否包含删除事件
  /// </summary>
  bool haseventdelete { get; }
  /// <summary>
  /// 是否包含导入事件
  /// </summary>
  bool haseventimport { get; }
  /// <summary>
  /// 是否包含导出事件
  /// </summary>
  bool haseventexport { get; }
 
  /// <summary>
  /// 更新操作
  /// </summary>
  void processrefresh(object sender, eventargs e);
  /// <summary>
  /// 增加操作
  /// </summary>
  void processadd(object sender, eventargs e);
  /// <summary>
  /// 编辑操作
  /// </summary>
  void processedit(object sender, eventargs e);
  /// <summary>
  /// 删除操作
  /// </summary>
  void processdelete(object sender, eventargs e);
  /// <summary>
  /// 导入操作
  /// </summary>
  void processimport(object sender, eventargs e);
  /// <summary>
  /// 导出操作
  /// </summary>
  void processexport(object sender, eventargs e);
 }

那么对于列表界面的基类窗体,我们除了让他继承自xtraform这个标准的窗体外,我们还让它实现对应的imenuaction接口,如下是列表界面基类basedock的窗体定义。

?
1
2
3
4
/// <summary>
/// 用于一般列表界面的基类
/// </summary>
public partial class basedock : xtraform, imenuaction

那么这个basedock的基类需要实现那些通用按钮事件的接口,如下所示。

?
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
#region 通用按钮菜单事件
  /// <summary>
  /// 更新按钮事件
  /// </summary>
  public event eventhandler refresh_menuevent;
  /// <summary>
  /// 根据事件判断是否有
  /// </summary>
  public bool haseventrefresh
  {
   get
   {
    return refresh_menuevent != null;
   }
  }
  /// <summary>
  /// 调用事件定义
  /// </summary>
  public void processrefresh(object sender, eventargs e)
  {
   if (refresh_menuevent != null)
   {
    refresh_menuevent(sender, e);
   }
  }
 
  .......................
 
  #endregion

通过基类的这样处理,我们就可以在具体列表窗体里,赋值给对应的事件就可以了。

3、列表窗体界面的处理

例如我们处理一个应用菜单的列表管理界面,定义窗体如下所示,继承了我们所实现imenuaction的基类basedock。

?
1
2
3
4
/// <summary>
/// 应用菜单管理
/// </summary>
public partial class frmapplicationmenu : basedock

那么我们需要指定它的几个处理事件,初始化代码如下所示。

?
1
2
3
4
5
6
7
8
9
10
11
12
/// <summary>
  /// 初始化公用菜单按钮的处理
  /// </summary>
  private void initmenuaction()
  {
   this.refresh_menuevent += (s, e) => { btnsearch_click(s, e); };
   this.add_menuevent += (s, e) => { btnaddnew_click(s, e); };
   this.edit_menuevent += (s, e) => { wingridviewpager1_oneditselected(s, e); };
   this.delete_menuevent += (s, e) => { wingridviewpager1_ondeleteselected(s, e); };
   this.import_menuevent += (s, e) => { btnimport_click(s, e); };
   this.export_menuevent += (s, e) => { btnexport_click(s,e);};
  }

这样我们就知道对应接口是如何和具体的页面事件发生关系了。

4、主窗体界面的处理

我们在构建主界面的左侧功能树的时候,我们通过树列表的选中事件加载对应的窗体,具体代码如下所示。

?
1
2
3
4
5
6
7
8
9
//处理树形菜单的点击操作,如果tag存在,则解析并加载对应的页面到多文档里面
 treeview.afterselect += (sender, e) =>
 {
  string tag = e.node.tag as string;
  if (!string.isnullorempty(tag))
  {
   loadpluginform(tag);
  }
 };

在这个函数里面,我们最终是通过配置动态构建对应的窗体,loadpluginform逻辑的最终实现的部分代码如下所示。

?
1
2
var form = loadmdiform(this.mainform, objtype, isshowdialog);
refreshbutton(form);

这里我们构建窗体或者激活窗体都获得一个窗体对象,然后刷新功能按钮的状态处理即可。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/// <summary>
 /// 更新按钮状态
 /// </summary>
 /// <param name="form">当前窗体</param>
 public void refreshbutton(form form)
 {
  this.currentform = form;
  imenuaction action = form as imenuaction;
  if (action != null)
  {
   //事件处理后再判断
   menubutton.refresh.enabled = (action.haseventrefresh);
   menubutton.add.enabled = (action.haseventadd);
   menubutton.edit.enabled = (action.haseventedit);
   menubutton.delete.enabled = (action.haseventdelete);
   menubutton.import.enabled = (action.haseventimport);
   menubutton.export.enabled = (action.haseventexport);
  }
 }

这样的处理,就可以实现了在主界面的多文档处理中,不管我们是新建一个列表窗体,还是激活切换到一个其他的窗体的时候,按钮的状态和对应的窗体绑定,实现随时更新显示。

Winform界面中实现通用工具栏按钮的事件处理方法

当然通用工具栏按钮的事件我们需要初始化,它是根据当前选中的窗体进行统一的处理的,具体代码如下所示。

?
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
73
74
/// <summary>
    /// 初始化菜单按钮的事件处理
    /// </summary>
    private void initmenuevent()
    {
      //事件绑定
      //先实现事件绑定
      menubutton.add.itemclick += (s, e) =>
      {
        if (currentform != null)
        {
          imenuaction action = currentform as imenuaction;
          if (action != null)
          {
            action.processadd(s, e);
          }
        }
      };
      menubutton.edit.itemclick += (s, e) =>
      {
        if (currentform != null)
        {
          imenuaction action = currentform as imenuaction;
          if (action != null)
          {
            action.processedit(s, e);
          }
        }
      };
      menubutton.delete.itemclick += (s, e) =>
      {
        if (currentform != null)
        {
          imenuaction action = currentform as imenuaction;
          if (action != null)
          {
            action.processdelete(s, e);
          }
        }
      };
      menubutton.import.itemclick += (s, e) =>
      {
        if (currentform != null)
        {
          imenuaction action = currentform as imenuaction;
          if (action != null)
          {
            action.processimport(s, e);
          }
        }
      };
      menubutton.export.itemclick += (s, e) =>
      {
        if (currentform != null)
        {
          imenuaction action = currentform as imenuaction;
          if (action != null)
          {
            action.processexport(s, e);
          }
        }
      };
      menubutton.refresh.itemclick += (s, e) =>
      {
        if (currentform != null)
        {
          imenuaction action = currentform as imenuaction;
          if (action != null)
          {
            action.processrefresh(s, e);
          }
        }
      };
    }

上面这个事件只需要绑定一次,不会造成按钮的事件多次绑定问题,虽然一次绑定,它的具体处理还是和当前窗体有关,它会把当前窗体转换为对应的imenuaction接口,然后调用对应的处理函数实现功能的绑定。

这篇就是我对于实现这种通用按钮事件处理的思路和具体逻辑代码,供大家参考学习,有错漏之处还请多多包涵。

原文链接:http://www.cnblogs.com/wuhuacong/archive/2017/11/29/7912916.html

延伸 · 阅读

精彩推荐
  • C#C#实现的文件操作封装类完整实例【删除,移动,复制,重命名】

    C#实现的文件操作封装类完整实例【删除,移动,复制,重命名】

    这篇文章主要介绍了C#实现的文件操作封装类,结合完整实例形式分析了C#封装文件的删除,移动,复制,重命名等操作相关实现技巧,需要的朋友可以参考下...

    Rising_Sun3892021-12-28
  • C#浅谈C# winForm 窗体闪烁的问题

    浅谈C# winForm 窗体闪烁的问题

    下面小编就为大家带来一篇浅谈C# winForm 窗体闪烁的问题。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    C#教程网7962021-12-21
  • C#C#基础之泛型

    C#基础之泛型

    泛型是 2.0 版 C# 语言和公共语言运行库 (CLR) 中的一个新功能。接下来通过本文给大家介绍c#基础之泛型,感兴趣的朋友一起学习吧...

    方小白7732021-12-03
  • C#C#直线的最小二乘法线性回归运算实例

    C#直线的最小二乘法线性回归运算实例

    这篇文章主要介绍了C#直线的最小二乘法线性回归运算方法,实例分析了给定一组点,用最小二乘法进行线性回归运算的实现技巧,具有一定参考借鉴价值,需要...

    北风其凉8912021-10-18
  • C#聊一聊C#接口问题 新手速来围观

    聊一聊C#接口问题 新手速来围观

    聊一聊C#接口问题,新手速来围观,一个通俗易懂的例子帮助大家更好的理解C#接口问题,感兴趣的小伙伴们可以参考一下...

    zenkey7072021-12-03
  • C#c#学习之30分钟学会XAML

    c#学习之30分钟学会XAML

    一个界面程序的核心,无疑就是界面和后台代码,而xaml就是微软为构建应用程序界面而创建的一种描述性语言,也就是说,这东西是搞界面的...

    C#教程网8812021-12-10
  • C#C# 后台处理图片的几种方法

    C# 后台处理图片的几种方法

    本篇文章主要介绍了C# 后台处理图片的几种方法,非常具有实用价值,需要的朋友可以参考下。...

    IT小伙儿10162021-12-08
  • C#Unity3D UGUI实现缩放循环拖动卡牌展示效果

    Unity3D UGUI实现缩放循环拖动卡牌展示效果

    这篇文章主要为大家详细介绍了Unity3D UGUI实现缩放循环拖动展示卡牌效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参...

    诗远3662022-03-11