Панель C # как контейнер MDI - PullRequest
3 голосов
/ 02 июня 2009

В C # я хочу создать панель, которая имеет свойства контейнера MDI, т.е. isMdiContainer = true.

Я пробовал что-то подобное

form.MDIParent = this.panel1;

Но это не работает. Есть предложения?

Ответы [ 3 ]

11 голосов
/ 30 июля 2009

Можно создать 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;
2 голосов
/ 02 июня 2009

Вы можете создать собственную форму, удалить все границы и панели инструментов, чтобы она выглядела как можно ближе к панели. Затем сделайте эту новую пользовательскую форму MdiContainer.

По сути, вы можете установить свойство IsMDIContainer только для формы. Это означает, что только форма может быть MdiContainer.

1 голос
/ 02 февраля 2016

Я использовал ответ Матиаса выше и смог избавиться от большинства вопросов, поднятых в комментариях. Я также создал вспомогательный класс для дочерних форм на случай, если кто-то захочет использовать его и / или сделать его лучше.

    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 (DataTableForm 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);
    }
}
...