C#MDI WinForms子激活

时间:2014-07-16 07:02:09

标签: c# winforms mdi mdichild

我遇到的问题是,当一个人从一个子表单切换到另一个子表单时,会发生一件奇怪的事情:要显示的表单以一种奇怪的方式出现,好像它已被最小化,恢复然后最大化,从而产生类似的效果几个绘画活动同时进行。

在这些情况下,问题不会出现(即一切正常):

  • 当使用 CTRL + TAB CTRL + SHIFT + TAB < / KBD>
  • 当儿童表格没有最大化时,只需更改表格的顺序/位置

可能相关;有一种方法可以用来显示表格,包括(和相关的):

  • child.Focus()
  • child.Show()
  • child.Activate()
  • child.Select()
  • child.BringToFront()

我的问题是,我到底应该打电话给谁?

修改

在我的情况下,我有以下代码可以使用,但仍会导致我上面描述的奇怪效果:

private void tabForms_MouseClick(object sender, MouseEventArgs e)
{
    // handle middle-mouse-button click (close)
    if (e.Button == System.Windows.Forms.MouseButtons.Middle)
    {
        // See: http://stackoverflow.com/a/745361
        TabPage tab = tabForms.TabPages.Cast<TabPage>().Where((t, i) => tabForms.GetTabRect(i).Contains(e.Location)).FirstOrDefault();
        if (tab != null && tab.Tag != null) (tab.Tag as Form).Close();
    }
    // handle left-mouse-button click (show)
    if ((tabForms.SelectedTab != null) && (tabForms.SelectedTab.Tag != null) && (ActiveMdiChild != tabForms.SelectedTab.Tag))
    {
        (tabForms.SelectedTab.Tag as Form).Select();
        (tabForms.SelectedTab.Tag as Form).Show();
    }
}

PS:如果没有.Select(),它就无法运作。虽然如果我将.Select().Show()替换为.Focus(),它似乎仍然有用。

1 个答案:

答案 0 :(得分:2)

这可能现在已经过时了,但为了这个问题的其他任何人的利益,有一个简单的解决方案。您可以调用Win32方法enter image description here,为表单提供窗口句柄,创建并打开/最大化您的表单,然后再次调用LockWindowUpdate并提供IntPtr.Zero值(如下所示)。

[DllImport("user32.dll", EntryPoint = "LockWindowUpdate", SetLastError = true,
        ExactSpelling = true, CharSet = CharSet.Auto,
        CallingConvention = CallingConvention.StdCall)]
public static extern long LockWindowUpdate(IntPtr hWndLock);

LockWindowUpdate禁用您提供的任何窗口句柄的绘图,第二次调用它,使用零IntPtr继续绘制窗口。一次只能锁定一个窗口。

你还需要另外两件事; DLL导入,以及System.Runtime.InteropServices的使用引用。这是DLL导入:

{{1}}