为什么隐藏和显示 mdi 子项会移动孩子



我有一个非常基本的开箱即用的mdiparent,它有许多mdichild和一个菜单项。 菜单项上的每个按钮隐藏所有窗体,然后显示与该按钮对应的窗体。

当我这样做时:

        //dontHide is the Form we want to show.
        for(int i = 0; i < this.MdiChildren.Length; i++)
        {
            if (this.MdiChildren[i] != dontHide)
            {
                this.MdiChildren[i].Visible = false;
            }
        }
        dontHide.Visible = true;

切换表单会导致打开的新表单位于旧表单的下方和右侧,但单击当前显示的表单的菜单项不会执行任何操作(如预期的那样(。

但是,当我这样做时:

        //dontHide is the Form we want to show.
        for(int i = 0; i < this.MdiChildren.Length; i++)
        {
            this.MdiChildren[i].Visible = false;
        } 
        dontHide.Visible = true;

即使单击当前可见表单的菜单项,也会导致它向右下角移动,就像打开新表单一样。 为什么?

编辑:

我还注意到,当将表单居中然后显示它时(因此您不会冒险让某人在移动它之前瞥见它(,将 visible 设置为 true 会完全重置我所做的任何居中。

这是由 Winforms 中模糊的实现细节引起的。 Windows 中内置的本机 MDI 支持不支持隐藏子窗口。 Winforms 通过在将子窗口的 Visible 属性设置为 false 时销毁子窗口来解决此限制。 并在将其设置回 true 时重新创建它。

这可能会产生各种副作用,当然,发生这种情况时,本机窗口的状态会丢失。 Winforms对从其属性再次恢复窗口有相当不错的支持。 但它不做的一件事是在同一位置重新创建窗口。 因此,你将看到它在新的 MDI 子窗口获得的位置重新创建,与上一个窗错。 我不清楚这是疏忽还是故意的,后者的可能性为95%。

否则很容易解决,您可以自己分配 Location 属性以将其恢复到原来的位置:

  var loc = dontHide.Location;        
  dontHide.Visible = true;
  dontHide.Location = loc;

或者只是将 MDI 子窗体的"起始位置"设置为"手动"。

最新更新