博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
工具栏ToolStrip能触发焦点控件的Leave、Validating、DataError等事件以验证数据 z
阅读量:6312 次
发布时间:2019-06-22

本文共 2468 字,大约阅读时间需要 8 分钟。

public class ToolStripEx : ToolStrip{    protected override void OnClick(EventArgs e)    {        base.OnClick(e);        Form fm = FindForm();        if (fm != null) { fm.Validate(); }    }}

 

之所以说几乎,是因为还是有一点不同,就是Form.Validate()并不会触发焦点控件的Leave事件,所以需要该事件的猿友恐怕还得继续沿用0尺寸Button法或另想他法。

另外发现ToolStrip还有个操蛋的问题,就是上述方法都只对 ToolStripButton的Click事件有效,但如果按钮是分离按钮ToolStripSplitButton,大家知道,按钮部分的单击事件就 该用ButtonClick而不是Click,单击按钮部分虽然也会先触发ToolStrip.Click事件进行验证,但不管验证结果如 何,ButtonClick都会被执行,不像ToolStripButton.Click那样,验证不过就不会执行。所以对付ButtonClick,在 找到更好的办法前,我还得在事件处理方法中加判断才行。真他娘的让人不省心。

----------------原文:2014-03-24---------------

如题,Winform码农大概都知道这样一个问题,就是当输入焦点仍处在 TextBox、DataGridViewCell等控件中时,如果单击普通Button、CheckBox等控件,那么该验证的会得到验证,该提交的会 提交,该报错的会报错,该被阻止的操作会被阻止。但如果单击的是工具栏上的项目(如ToolStripButton,之所以说项目而不是控件,你懂的), 是不会触发焦点控件的验证事件的,而是会直接执行按钮事件,这样带来的影响相信大家深有体会。总之不解决ToolStrip的这个问题我不会幸福。先看办 法:

/// /// 工具栏(无右侧竖线、无手柄、可触发其它控件验证)///  public class ToolStripEx : ToolStrip { readonly Button btn;//定义一个用来转移焦点的控件,如Button public ToolStripEx() { //初始化并指定控件尺寸为0,0。因为你不会希望这个按钮被看到 btn = new Button { Width = 0, Height = 0 }; //下面为可选项 //让工具栏在视觉上更地道。如被按下的ToolStripButton更明显,否则只有一个惨淡的线框 ToolStripManager.VisualStylesEnabled = false; //不显示拖曳抓柄 GripStyle = ToolStripGripStyle.Hidden; } //在工具栏获得句柄后将控件添加进窗体,之所以不在构造函数中做这事是因为那个时候窗体也许还是null protected override void OnHandleCreated(EventArgs e) { base.OnHandleCreated(e); Form fm = this.FindForm(); if (fm != null) { fm.Controls.Add(btn); }//这样添加后,btn.Location会是0,0 } //在工具栏被碰到时(其实选用其它类似事件也行)将焦点转移到btn上,以此触发焦点控件的验证 //注意虽然是工具栏的Click,但经过实践点击其中的子项都会优先触发该事件 //所以当焦点控件验证通不过时,不会再执行子项的Click事件,这一点我想是由win32消息机制实现的 protected override void OnClick(EventArgs e) { base.OnClick(e); btn.Focus(); } //可选。把工具栏最右边的1px竖线K掉,这种瑕疵对于我来说简直不能忍受,草泥马微软,有病 protected override void OnPaint(PaintEventArgs e) { e.Graphics.SetClip(new Rectangle(0, 0, Width - 1, Height)); base.OnPaint(e); } }

办法很简单,就是在点击工具栏时先把焦点移到其它能正常获得焦点的控件上,以此来触发先前控件的Leave/Validating/DataError等事件。

其实为了解决这个问题我颇费了一番周折,最开始想到的其实就是这招,但觉得猥琐了 点,作为一个有追求的码农,我认为应该从消息层面去解决,所以一开始就把这个阴招放在一边,专心捣鼓消息。开始我认为这个问题的本质是因为,工具栏就像 Panel之类的控件,是得不到焦点的控件,不像Button之流,能够让其他控件的焦点转移过来,所以才有这个问题。那么我就想通过调用win32 API,让工具栏能发出与Button一样的消息,让焦点控件受骗,以为点到的是Button,从而验证自己的数据,移交自己的焦点。经过多番实践,确实 让工具栏获得了焦点,让焦点控件失去焦点,用Spy++看焦点控件接收到的消息也与点击Button接收到的消息看起来一样了,但仍然不会触发验证,这就 扯蛋了~我那个沮丧啊。BTW~其实给工具栏设置SetStyle(ControlStyles.Selectable, true)也可以达到同样目的,但一样解决不了问题。

也许是还没摸透问题的本质,也许是win32消息还是玩不转~总之是经历过若干次失败的尝试,我不得不放弃高大上的解决办法,这才回头来重新拾起猥琐方案,所以文中办法其实是妥协的结果,难免心有不甘,等他日机缘到了,我定再次尝试“正统”的解决办法。

转载地址:http://ydhxa.baihongyu.com/

你可能感兴趣的文章
《树莓派开发实战(第2版)》——1.1 选择树莓派型号
查看>>
在 Linux 下使用 fdisk 扩展分区容量
查看>>
结合AlphaGo算法和大数据的量化基本面分析法探讨
查看>>
如何在 Ubuntu Linux 16.04 LTS 中使用多个连接加速 apt-get/apt
查看>>
《OpenACC并行编程实战》—— 导读
查看>>
机器学习:用初等数学解读逻辑回归
查看>>
如何在 Ubuntu 中管理和使用逻辑卷管理 LVM
查看>>
Oracle原厂老兵:从负面案例看Hint的最佳使用方式
查看>>
把自己Github上的代码添加Cocoapods支持
查看>>
C语言OJ项目参考(2493)四则运算
查看>>
零基础入门深度学习(二):神经网络和反向传播算法
查看>>
find和xargs
查看>>
数据结构例程—— 交换排序之快速排序
查看>>
WKWebView代理方法解析
查看>>
IOS定位服务的应用
查看>>
[SMS&WAP]实例讲解制作OTA短信来自动配置手机WAP书签[附源码]
查看>>
IOS中图片(UIImage)拉伸技巧
查看>>
【工具】系统性能查看工具 dstat
查看>>
基于zepto或jquery的手机端弹出框成功,失败,加载特效
查看>>
php引用(&)
查看>>