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); } }