【问题标题】:C# Panel As MDI ContainerC# 面板作为 MDI 容器
【发布时间】:2010-10-30 18:57:48
【问题描述】:

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

我试过这样的

form.MDIParent = this.panel1;

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

【问题讨论】:

    标签: c# forms panel mdi


    【解决方案1】:

    我在上面使用了 Mathias 的答案,并且能够摆脱 cmets 中提出的大部分问题。我还为子表单创建了一个辅助类,以防有人想使用它和/或改进它。

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

    【讨论】:

      【解决方案2】:

      可以创建一个 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;
      

      【讨论】:

      • MathiasJ,
        我尝试了您的解决方案,但遇到了一个问题:当您最大化子窗体时,其客户区适合所有面板可用空间和标题栏(包含三个按钮 minimize minimize 和 close) 无处显示......所以你不能再看到其他孩子......有什么想法吗?再见詹尼
      • 在我想用作 MDI 容器的自定义控件上,这对我来说非常有效。需要进行一些调整(包括我上面的评论),但除此之外:干得好。
      【解决方案3】:

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

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

      【讨论】:

      • 我不知道你在做什么,但你不能有嵌套的 MDI 表单:(
      • 我终于明白了你对自定义表单的看法。使其成为用户控件:D
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-17
      • 1970-01-01
      • 1970-01-01
      • 2021-05-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多