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

1、界面功能介绍

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

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

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

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

2、界面窗体基类的处理

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

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

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

    /// <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的接口定义如下所示。

    /// <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的窗体定义。

    /// <summary>/// 用于一般列表界面的基类/// </summary>public partial class BaseDock : XtraForm, IMenuAction

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

        #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。

    /// <summary>/// 应用菜单管理/// </summary>public partial class FrmApplicationMenu : BaseDock

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

        /// <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、主窗体界面的处理

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

    //处理树形菜单的点击操作,如果TAG存在,则解析并加载对应的页面到多文档里面treeView.AfterSelect += (sender, e) =>{string tag = e.Node.Tag as string;if (!string.IsNullOrEmpty(tag)){LoadPlugInForm(tag);}};

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

    var form = LoadMdiForm(this.mainForm, objType, isShowDialog);RefreshButton(form);

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

    /// <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);}}

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

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

        /// <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接口,然后调用对应的处理函数实现功能的绑定。

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

Winform界面中实现通用工具栏按钮的事件处理相关推荐

  1. Winform界面中主从表编辑界面的快速处理

    在Winform开发中,我们往往除了常规的单表信息录入外,有时候设计到多个主从表的数据显示.编辑等界面,单表的信息一般就是控件和对象实体一一对应,然后调用API保存即可,主从表就需要另外特殊处理,本随 ...

  2. wordpress怎么修改html,WordPress后台编辑器HTML模式界面中添加修改删除按钮

    在WordPress编辑器HTML模式界面中添加 按钮一文中,我大致介绍了怎么在后台添加一些自定义的按钮,本文则更为详细全面的对wordpress后台编辑器HTML模式下的按钮自定义进行详解,以让开发 ...

  3. 在 Directory Opus 中添加自定义的工具栏按钮提升效率

    使用 Directory Opus 替代 Windows 自带的文件资源管理器来管理你计算机上的文件可以极大地提高你的文件处理效率. Directory Opus 自定义的工具栏按钮可以执行非常复杂的 ...

  4. CDR插件开发之CPG插件010 - 在CPG插件中实现创建工具栏按钮(下篇,基于X4)

    在上篇文章中,通过代码在标准工具栏上创建了一个自定义图标,但读者会发现这个图标是禁用状态,无法点击.本文将继续完善之前的代码,实现工具栏按钮的启用.动态启用,并为按钮添加单击响应事件,单击后,在当前页 ...

  5. Winform界面中实现菜单列表的动态个性化配置管理

    在我们一般的应用系统里面,由于系统是面向不同类型的用户,我们所看到的菜单会越来越多,多一点的甚至上百个,但是我们实际工作接触的菜单可能就是那么几个,那么对于这种庞大的菜单体系,寻找起来非常不便.因此对 ...

  6. 原文地址:一共470多例winform 界面特效的源码

    转载自:http://blog.sina.com.cn/s/blog_6cad1bf401013pnx.html 一共470多例winform 界面特效的源码. 窗体与界面设计... 9 实例001  ...

  7. 一共470多例winform 界面特效的源码

    http://blog.sina.com.cn/s/blog_69dcf6a80100uakc.html 一共470多例winform 界面特效的源码. 窗体与界面设计... 9 实例001  带历史 ...

  8. 470例 Winform界面特效的源码

    一共470多例winform 界面特效的源码. 窗体与界面设计... 9 实例001 带历史信息的菜单 10 实例002 菜单动态合并 12 实例003 像开始菜单一样漂亮的菜单... 14 实例00 ...

  9. 470多例winform 界面特效

    实例001  带历史信息的菜单    10 实例002  菜单动态合并    12 实例003  像开始菜单一样漂亮的菜单... 14 实例004  任务栏托盘菜单    15 实例005  可以拉伸 ...

  10. matlab 按钮组设置,MATLAB中的单选按钮和按钮组

    MATLAB GUI中的单选按钮和按钮组 matlabGUI界面中的单选(radiobutton)按钮不提供互斥功能,要通过程序实现. 方法一: 假设有3个radiobutton,分别为radiobu ...

最新文章

  1. usaco contact
  2. 学习别跟我谈兴趣 No.88
  3. NLP 解决方案是如何被深度学习改写的?
  4. 湖北省政府网站刊文:感染新冠肺炎的适龄男性应进行生育力检查
  5. python模拟sed在每行添加##
  6. JavaScript数据结构与算法——集合
  7. SQL必知必会-视图
  8. Vue2.0 + ElementUI 手写权限管理系统后台模板(三)——页面搭建
  9. 关于电脑的基础知识_改装小白必看的汽车音响改装基础知识!
  10. 介绍一个不错的图书下载网站-顺便推荐几本书
  11. 诺瓦-测试-面经(一面+二面)
  12. JAVA多线程模拟火车站售票大厅
  13. 磁共振t1t2信号记忆顺口溜_【 磁共振t1与t2是啥意义】_特点_特征-大众养生网
  14. python实现转置矩阵_用Python转置矩阵?
  15. 从0开始构建蓝牙耳机研发环境
  16. 二手市场回收基于微信小程序和app两种应用开发uniapp
  17. 彻底删除EFI启动项
  18. writely is cool!
  19. 文本分类——特征选择概述
  20. 使用python进行新浪微博粉丝爬虫

热门文章

  1. Unity sendmessage发送多个参数
  2. SpringMVC 异常记录
  3. syntax error : missing ';' before identifier 'oper'解决方法
  4. asp.net membership 配置错误
  5. iOS UICollectionView 注册步骤、使用方法以及 各种问题 和坑点
  6. 六大设计原则(三)DIP依赖倒置原则
  7. Monthly数据类型
  8. Android新增输入设备
  9. 如何创建和使用文档库 - [MOSS 2007应用日记]
  10. 豆瓣评分8.0以上数据分析R、MySQL、Python等书籍,45本包邮送到家