4

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

我尝试过这样的事情

form.MDIParent = this.panel1;

但这不起作用。有什么建议么?

4

3 回答 3

11

可以创建一个 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;
于 2009-07-30T07:38:58.923 回答
2

您可以创建自定义表单,删除所有边框和工具栏,使其看起来尽可能接近面板。然后使这个新的自定义表单成为 MdiContainer。

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

于 2009-06-02T19:16:58.797 回答
2

我在上面使用了 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;

    /// <summary>
    /// The current active child form
    /// </summary>
    public Form ActiveMDIWnd
    {
        get;
        set;
    }

    /// <summary>
    /// List of available forms
    /// </summary>
    public List<MdiClientForm> ChildForms = new List<MdiClientForm>();

    /// <summary>
    /// Std constructor
    /// </summary>
    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);
    }

    /// <summary>
    /// Add this Form to our list of children and set the MDI relationship up
    /// </summary>
    /// <param name="child">The new kid</param>
    /// <returns>The new kid</returns>
    public MdiClientForm AddChild(MdiClientForm child)
    {
        child.MyMdiContainer = this;
        child.MdiParent = MdiForm;
        ChildForms.Add(child);

        return child;
    }

    /// <summary>
    /// The user sent a "restore" command, so issue it to all children
    /// </summary>
    public void RestoreChildForms()
    {
        foreach (MdiClientForm child in ChildForms)
        {
            child.WindowState = FormWindowState.Normal;
            child.MaximizeBox = true;
            child.MinimizeBox = true;
        }
    }

    /// <summary>
    /// Send the Activated message to the owner of this panel (if they are listening)
    /// </summary>
    /// <param name="child">The child that was just activated</param>
    public void ChildActivated(MdiClientForm child)
    {
        ActiveMDIWnd = child;

        if (OnChildActivated != null)
            OnChildActivated(this, child);
    }

    /// <summary>
    /// The child closed so remove them from our available form list
    /// </summary>
    /// <param name="child">The child that closed</param>
    public void ChildClosed(MdiClientForm child)
    {
        ChildForms.Remove(child);
    }
}

/// <summary>
/// A wrapper class for any form wanting to be an MDI child of an MDI Panel
/// </summary>
public class MdiClientForm : Form
{
    /// <summary>
    /// My parent MDI container
    /// </summary>
    public MdiClientPanel MyMdiContainer { get; set; }

    /// <summary>
    /// Standard Constructor
    /// </summary>
    public MdiClientForm()
    {
        Activated += OnFormActivated;
        FormClosed += OnFormClosed;
    }

    /// <summary>
    /// Reports back to the container when we close
    /// </summary>
    void OnFormClosed(object sender, FormClosedEventArgs e)
    {
        MyMdiContainer.ChildClosed(this);
    }

    /// <summary>
    /// Reports back to the parent container when we are activated
    /// </summary>
    private void OnFormActivated(object sender, EventArgs e)
    {
        MyMdiContainer.ChildActivated(this);
    }
}
于 2016-02-02T13:19:52.263 回答