容器forms的控件是否以子forms出现?

在容器forms中,我有菜单和按钮来打开表格。 在此处输入图像描述

在这里我遇到一个问题,当我打开任何forms这些按钮和标签来到新打开的表格。 在此处输入图像描述

请指导我如何管理这个问题? 我想打开一个新表单并将这些容器表单的控件保留在它的后台。

我也遇到了同样的问题。 我有一个替代解决方案,如下所述:

  1. 插入计时器控件
  2. 我在面板容器中添加了控件
  3. 并做了以下

    private void timer1_Tick(object sender, EventArgs e) { if ((int)MdiChildren.GetLength(0) > 0) { panel1.Visible = false; } else { panel1.Visible = true; } } 

我想我明白你做了什么。 您正在使用MDI并将菜单标签和按钮放在MDI父窗体上。 您使用MDI客户端窗口执行了某些操作,通常是深灰色。 也许你想出了如何更改其BackColor或更改Windows系统颜色。 是的,你的屏幕拍摄了结果。 问题是MDI客户端表单是MDI客户端窗口的父级。 这使它们显示您放在父窗体上的控件后面

没有解决方法,您将不得不更改您的UI。 要保留MDI,请将Panel放在父窗体上,并将其Dock属性设置为Left。 移动菜单控件。 MDI客户端窗口现在将缩小,占用父窗体的其余部分。 儿童forms将限制自己到那个地区。 痛苦的一点是,您必须重新组织菜单以适应面板中可用的小得多的空间。

如果它是MDI应用程序并且您将控件放在父窗口中,那么它们将显示在任何创建的子窗口之上。 您还需要在子窗口中显示菜单,而不是在父窗体上。

看看这篇文章和这篇文章 。

特别是这个:

父表单可能不包含任何控件。 >

编辑:添加了附加信息

@Hans Passant有正确的答案,但您也可以通过不使用MDI表格来解决您的问题。 一些选择:

  • 使用单独的表单:有一个菜单表单,通常是大/最大化,并通过将其Parent属性设置为菜单表单在其前面启动子表单,或者
  • 使用单个表单,但使用对接库(我以前使用过DockPanel Suite )。 这实际上是MDI表单的重新实现,具有额外的function。 这是一个可以运行的工作,但它可以让你构建一些漂亮的UI。

但是,这两者都需要对UI代码进行重大更改。

这里的主要技巧是将子表单视为控件。 您将像任何其他控件一样创建子表单。 当您使用此方法时,您必须将其TopLevel设置为false – 否则它将无法工作。

以下代码行用于创建子表单:

 Form childForm = new Form(); //initialize a child form childForm.TopLevel = false; //set it's TopLevel to false Controls.Add(childForm); //and add it to the parent Form childForm.Show(); //finally display it childForm.BringToFront(); //use this it there are Controls over your form. 

更多细节在这里

似乎该表单是其他子控件的兄弟。 你必须打开它作为那个窗口的孩子吗? 它不能像非modal dialog而不是该主窗体的子窗口吗?

如果它必须在那个主要forms和那些控件的兄弟中,那么你将不得不设置它的Z顺序。 没有属性,因此您将不得不关注Win32 API调用SetWindowPos

 [DllImport("user32.dll", EntryPoint = "SetWindowPos")] public static extern bool SetWindowPos( int hWnd, // window handle int hWndInsertAfter, // placement-order handle int X, // horizontal position int Y, // vertical position int cx, // width int cy, // height uint uFlags); // window positioning flags const uint SWP_NOSIZE = 0x1; const uint SWP_NOMOVE = 0x2; const uint SWP_SHOWWINDOW = 0x40; const uint SWP_NOACTIVATE = 0x10; 

并称之为:

 SetWindowPos((int)form.Handle, // that form (int)insertAfter.Handle, // some other control 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW | SWP_NOACTIVATE); 

在显示每个子表单后,在每个子表单上调用BringToFront()。 或者,将它挂钩到每个子窗体的OnLoad方法:

 childForm.OnLoad += (s, e) => (s as Form).BringToFront(); 

我有这个问题并以这种方式解决了它:

 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Windows.Forms; namespace WindowsFormsApplication1 { public partial class Form1 : Form { [DllImport("user32.dll", SetLastError = true)] static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent); Form2 F2; public Form1() { InitializeComponent(); F2 = new Form2(); } private void Form1_Load(object sender, EventArgs e) { Panel P1 = new Panel(); P1.Location = new Point(0, 0); P1.Height = this.Height; P1.Width = this.Width; P1.BackColor = Color.Transparent; this.Controls.Add(P1); SetParent(F2.Handle, P1.Handle); F2.Owner = this; F2.Show(); } }