MessageBox改变了一些看似无关的东西

本文关键字:改变 MessageBox | 更新日期: 2023-09-27 18:11:43

这是我的设置:我有一个TabControl与许多选项卡,并在最后一个选项卡,我有一个UserControl添加到TabPage。这个UserControl有一个VisibleChanged事件,用来检查它是否可见,如果它可见,则使用CustomCommand()显示某些信息。

void MyUserControl_VisibleChanged(object sender, EventArgs e)
        {
            //MessageBox.Show("");
            UserControl us = sender as UserControl;
            if (us.Visible)
            {
                CustomCommand();
            }
            //MessageBox.Show("");
        }

这里是问题:这个代码将错误地认为UserControl是可见的,当它不是,和CustomCommand()将运行时,它不应该。当注释掉的MessageBox函数在任何一个位置上都没有注释时,UserControl被正确地视为不可见,当然,直到TabPage被选中。有人知道为什么会这样吗?

MessageBox改变了一些看似无关的东西

仅仅把它放在TabPage上并不能解释这个问题。必须涉及其他布局事件,使控件稍后实际可见。MessageBox.Show()调用提供了一个时间机器,可以通过延迟来检查可见属性。

让代码稍后运行的标准技术,MessageBox的方式,是通过使用Control.BeginInvoke()方法。当所有事件都被触发和处理并且UI线程再次空闲时,委托目标运行。这样的:

void MyUserControl_VisibleChanged(object sender, EventArgs e)
{
    UserControl us = sender as UserControl;
    this.BeginInvoke(new Action(() => {
        if (us.Visible)
        {
            CustomCommand();
        }
    });
}

不确定这是否会对您有所帮助,但是Visible_Changed事件有一个奇怪的不对称行为:

  • 当控件的可见属性发生变化时,为true或false,它就会被引发。

  • 它也被引发每当父的可见属性更改为true和仅为true!

  • 我不能通过隐藏另一个控件的控件来引发事件,或者通过MessageBox来引发事件。

我不知道你的应用程序是如何工作的,所以我无法复制。但我确实注意到,当更改选项卡时,TabPage上控件的Visible_Changed事件确实会引发,每当页面选中时(但不是当它未选中时)。我也不知道。

您可以尝试捕获另一个方向,通过使用SelectionIndexChanged或通过挂钩到TabPage的VisibleChanged事件。这在IDE中是不可见的,但它确实以两种方式工作:

tabPagexyz2.VisibleChanged += tabPagexyz_VisibleChanged;
void tabPage2_VisibleChanged(object sender, EventArgs e)
{
     // do something
}

我看到了关于UI竞争条件背后的疯狂猜测,我对此表示怀疑。这至少可以解释为什么MessageBox会产生影响。如果您想进行测试,您可以将其替换为一个邪恶的Applictaion.DoEvents