zoukankan      html  css  js  c++  java
  • Winforms: 不能在Validating时弹出有模式的对话框

    一、问题重现步骤:                                              

    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中弹出有模式的对话框。

    本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/cadcisdhht/archive/2009/05/23/4210720.aspx

  • 相关阅读:
    骗子网站,X毛都没有,骗我九十九
    xssgame挑战wp
    某xss挑战赛闯关笔记
    committed与urgent的区别
    KahnProcessNetwork的Python实现
    网络层数
    使用matlab用优化后的梯度下降法求解达最小值时参数
    使用matlab画半透明椭圆
    关系代数(Relation Algebra)与SQL语句的对应关系
    one vs all -- 将01分类器用于多类分类问题
  • 原文地址:https://www.cnblogs.com/rxie/p/1760825.html
Copyright © 2011-2022 走看看