Winforms: 不能在Validating时弹出有模式的对话框
来源:互联网 发布:php财务系统源码 编辑:程序博客网 时间:2024/06/05 09:18
一、问题重现步骤:
1. 新建一个Winforms项目;
2. 在项目中添加一个UserControl,并在里面添加两个TextBox:textBox1和textBox2;
3. 编译该项目;
4. 在Toolbox里找到我们添加的UserControl1,并在Form1上添加一个实例userControl11;
5. 在Form1添加一个TextBox,命名为textBox3;
6. 为textBox3添加如下事件处理器(Event Handler):
private void textBox3_Validating(object sender, CancelEventArgs e)
{
MessageBox.Show("textBox3_Validating", "Info");
}
7. 编译、运行;
8. 鼠标点击textBox3,再点击userControl11上的textBox2。
9. 因textBox3_Validating被触发,会弹出一个消息框。点击确认按钮让消息框消失。此时光标在textBox2中;
10. 用键盘输入“abc”
结果:“abc”出现在textBox1中
二、分析:
MessageBox是一个有模式的对话框。当出现一个MessageBox的时候,该MessageBox有自己的消息队列,同时屏蔽Form1的消息队列。所以一旦MessageBox弹出来的时候,Form1就不能响应键盘、鼠标等消息了。当我们点击确认按钮让MessageBox消失的时候,在MessageBox的内部会重新把焦点(Focus)设回到Form1,这样Form1可以继续响应消息。当把焦点设回到Form1时,Winforms会试着让焦点停在Form1上一个可以设置焦点的控件上,在我们这个场景下找到的是textBox1。由于我们点击了textBox2,Winforms同时有试着把焦点设到textBox2,此时就出现了我们前面看到的问题:焦点看起来是在textBox2(因为光标在textBox2),但实际上在textBox1(输入的字符在textBox1)。
textBox3_Validating是在Form1的消息处理过程中被触发了,如果在该事件处理器中弹出一个有模式的对话框,Form1上的消息处理被屏蔽。当焦点重新回到Form1上的时候,它的消息队列已经混乱了。
让textBox3_Validating更加复杂的是,Validating是一个可以取消的事件。当e.Cancel为true的时候,事件处理完后焦点应该仍停在textBox3上;当e.Cancel为false的时候,焦点会设到下一个控件上。在我们的场景里,是textBox2。也就是说,在textBox3_Validating处理结束后,下一个焦点会在那个控件上还是未知的,取决于e.Cancel的值。可是如果弹出一个对话框,在对话框消失的时候会去设置焦点,这个时候无论设到哪个控件上都有可能是错误的。
三、建议
不要在Validating的处理器中弹出对话框。这样会打乱消息队列,很容易导致错误。
如果想绕过(不是解决)前面提到问题,一个办法是用BeginInvoke来弹出对话框。代码如下:
private void textBox3_Validating(object sender, CancelEventArgs e)
{
textBox3.BeginInvoke(new ShowMessageBoxDelegate(ShowMessageBox));
}
private delegate void ShowMessageBoxDelegate();
private void ShowMessageBox()
{
MessageBox.Show("textBox3_Validating", "Info");
}
值得一提的是,该方法不能解决所有的问题。比如当焦点在textBox3的时候去点击textBox2,textBox2是不能收到WM_LBUTTONUP的消息的。因此还是回到前面的建议,不要在Validating中弹出有模式的对话框。
- Winforms: 不能在Validating时弹出有模式的对话框
- OutLook样式类使用过程,弹出模式对话框时候,鼠标不能点击对话框按钮,的问题。
- 在Update Panel里弹出模式对话框
- 解决Chrome在部分网站不能弹出上传文件对话框的办法及flash问题
- 解决Chrome在部分网站不能弹出上传文件对话框的办法及flash问题
- 有模式的弹出窗口
- 在有EditText控件的AlertDialog对话框中自动弹出输入法
- 弹出全屏显示的网页模式对话框
- 在使用模式对话框时,实时改变对话框的位置
- iis5.1设置好后不能访问,并在开启时弹出"服务器没有及时响应或控制请求"的对话框,请问是怎么回事啊?
- 弹出自定义模式对话框
- Android WebView 不能弹出alert的对话框的处理
- Flash player debug版本不能弹出运行时错误提示对话框的解决办法
- EVC中怎样使弹出的对话框不能移动
- 有对话框弹出时,VB的Timer不工作的原因
- Winforms: Application.Idle不能在非UI线程里注册
- 弹出模式对话框和弹出非模式对话框
- DIV全屏-弹出模式对话框
- 近期学习感受
- 浅谈领域逻辑和业务逻辑
- c#之MessageBox
- 脚本攻击防范策略完全篇
- python处理重定位数据
- Winforms: 不能在Validating时弹出有模式的对话框
- win2003结构化安全清单
- ACCESS的真假:三、往一个表中插入10万条记录的速度小于插入1万条记录吗?
- 网络通信编程初步:windows socket 程序示例
- Win2003网络服务器安全
- 保护SQL2000安全的十个技巧
- SQL Server 2000的安全配置
- 使index.jsp直接转入action
- 彻底删除系统备份后产生的C_PAN.GHO文件