C#Panel作为MDI容器

在C#中,我想创建一个具有MDI容器属性的面板,即。 isMdiContainer = true。

我试过这样的事

form.MDIParent = this.panel1; 

但那不行。 有什么建议?

您可以创建自定义表单,删除所有边框和工具栏,使其尽可能贴近面板。 然后将新的自定义表单设为MdiContainer。

基本上,您只能在Form上设置IsMDIContainer属性。 这意味着只有表单可以是MdiContainer。

可以创建一个MDI面板并在该面板中显示表单,类似下面的代码就可以完成这项工作

Mdi-Panel定义:

 public class MdiClientPanel : Panel { private Form mdiForm; private MdiClient ctlClient = new MdiClient(); public MdiClientPanel() { base.Controls.Add(this.ctlClient); } public Form MdiForm { get { if (this.mdiForm == null) { this.mdiForm = new Form(); /// set the hidden ctlClient field which is used to determine if the form is an MDI form System.Reflection.FieldInfo field = typeof(Form).GetField("ctlClient", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); field.SetValue(this.mdiForm, this.ctlClient); } return this.mdiForm; } } } 

用法:

 /// mdiChildForm is the form that should be showed in the panel /// mdiClientPanel is an instance of the MdiClientPanel myMdiChildForm.MdiParent = mdiClientPanel1.MdiForm; 

我使用了上面的Mathias的答案,并且能够摆脱评论中提出的大多数问题。 我也为子表单创建了一个帮助类,以防任何人想要使用它和/或使其更好。

  public class MdiClientPanel : Panel { private MdiClient _ctlClient = new MdiClient(); // Callback event when a child is activated public delegate void ActivateHandler(object sender, MdiClientForm child); public event ActivateHandler OnChildActivated; ///  /// The current active child form ///  public Form ActiveMDIWnd { get; set; } ///  /// List of available forms ///  public List ChildForms = new List(); ///  /// Std constructor ///  public MdiClientPanel() { base.Controls.Add(_ctlClient); } private Form _mdiForm = null; public Form MdiForm { get { if (_mdiForm == null) { _mdiForm = new Form(); // Set the hidden _ctlClient field which is used to determine if the form is an MDI form System.Reflection.FieldInfo field = typeof(Form).GetField("ctlClient", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); field.SetValue(_mdiForm, _ctlClient); } return _mdiForm; } } private void InitializeComponent() { SuspendLayout(); ResumeLayout(false); } ///  /// Add this Form to our list of children and set the MDI relationship up ///  /// The new kid /// The new kid public MdiClientForm AddChild(MdiClientForm child) { child.MyMdiContainer = this; child.MdiParent = MdiForm; ChildForms.Add(child); return child; } ///  /// The user sent a "restore" command, so issue it to all children ///  public void RestoreChildForms() { foreach (DataTableForm child in ChildForms) { child.WindowState = FormWindowState.Normal; child.MaximizeBox = true; child.MinimizeBox = true; } } ///  /// Send the Activated message to the owner of this panel (if they are listening) ///  /// The child that was just activated public void ChildActivated(MdiClientForm child) { ActiveMDIWnd = child; if (OnChildActivated != null) OnChildActivated(this, child); } ///  /// The child closed so remove them from our available form list ///  /// The child that closed public void ChildClosed(MdiClientForm child) { ChildForms.Remove(child); } } ///  /// A wrapper class for any form wanting to be an MDI child of an MDI Panel ///  public class MdiClientForm : Form { ///  /// My parent MDI container ///  public MdiClientPanel MyMdiContainer { get; set; } ///  /// Standard Constructor ///  public MdiClientForm() { Activated += OnFormActivated; FormClosed += OnFormClosed; } ///  /// Reports back to the container when we close ///  void OnFormClosed(object sender, FormClosedEventArgs e) { MyMdiContainer.ChildClosed(this); } ///  /// Reports back to the parent container when we are activated ///  private void OnFormActivated(object sender, EventArgs e) { MyMdiContainer.ChildActivated(this); } }