目录

1、问题描述:

2、解决方案: 

3、总结: 


1、问题描述:

        现在我们创建了一个新的Winform窗体,然后我们在其中按顺序新建了几个容器类控件。比方说三个 groupBox

创建顺序为groupBox1、groupBox2、groupBox3
​​

        这个时候我们想要用这三个 groupBox 从上至下将整个 Form1 界面划分为三块,那我们就需要设置这三个 groupBoxDock 属性:

        自然而然地,我们想到了两种 Dock 属性组合方案: 

Dock 属性groupBox1groupBox2groupBox3
方案一TopTopFill
方案二TopFillButtom

        使用方案一没有啥问题,最终效果如下图:

        但是使用方案二,问题就出现了:

        当我们选中 groupBox2 时,可以明显观察到 groupBox2 的边框(图中虚线)把 groupBox3 也包含进去了;而方案一没有出现这种情况。这不是我们期望看到的情况。 

2、解决方案: 

        解决方案也很简单,问题与控件的添加顺序有关。我们打开 Form1.Designer.cs 窗体设计代码,找到 #region Windows 窗体设计器生成的代码 中注释为 Form1 的那部分代码:

namespace WindowsFormsApp1
{
    partial class Form1
    {
        /// <summary>
        /// 必需的设计器变量。
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// 清理所有正在使用的资源。
        /// </summary>
        /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows 窗体设计器生成的代码

        /// <summary>
        /// 设计器支持所需的方法 - 不要修改
        /// 使用代码编辑器修改此方法的内容。
        /// </summary>
        private void InitializeComponent()
        {
            this.groupBox1 = new System.Windows.Forms.GroupBox();
            this.groupBox2 = new System.Windows.Forms.GroupBox();
            this.groupBox3 = new System.Windows.Forms.GroupBox();
            this.SuspendLayout();
            // 
            // groupBox1
            // 
            this.groupBox1.Dock = System.Windows.Forms.DockStyle.Top;
            this.groupBox1.Font = new System.Drawing.Font("微软雅黑", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
            this.groupBox1.ForeColor = System.Drawing.SystemColors.Highlight;
            this.groupBox1.Location = new System.Drawing.Point(0, 0);
            this.groupBox1.Name = "groupBox1";
            this.groupBox1.Size = new System.Drawing.Size(800, 100);
            this.groupBox1.TabIndex = 0;
            this.groupBox1.TabStop = false;
            this.groupBox1.Text = "groupBox1";
            // 
            // groupBox2
            // 
            this.groupBox2.Dock = System.Windows.Forms.DockStyle.Fill;
            this.groupBox2.Font = new System.Drawing.Font("微软雅黑", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
            this.groupBox2.ForeColor = System.Drawing.SystemColors.Highlight;
            this.groupBox2.Location = new System.Drawing.Point(0, 100);
            this.groupBox2.Name = "groupBox2";
            this.groupBox2.Size = new System.Drawing.Size(800, 350);
            this.groupBox2.TabIndex = 1;
            this.groupBox2.TabStop = false;
            this.groupBox2.Text = "groupBox2";
            // 
            // groupBox3
            // 
            this.groupBox3.Dock = System.Windows.Forms.DockStyle.Bottom;
            this.groupBox3.Font = new System.Drawing.Font("微软雅黑", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
            this.groupBox3.ForeColor = System.Drawing.SystemColors.Highlight;
            this.groupBox3.Location = new System.Drawing.Point(0, 350);
            this.groupBox3.Name = "groupBox3";
            this.groupBox3.Size = new System.Drawing.Size(800, 100);
            this.groupBox3.TabIndex = 1;
            this.groupBox3.TabStop = false;
            this.groupBox3.Text = "groupBox3";
            // 
            // Form1    这里这里!重点在这儿哦!!
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(800, 450);
            //
            //设计代码中调用Add方法的顺序决定了Winform窗体控件的添加顺序
            //由下方代码可知实际在生成Form1窗口时这三个groupBox控件的添加顺序
            //和我们设计时添加它们的顺序是相反的
            //
            this.Controls.Add(this.groupBox3);        
            this.Controls.Add(this.groupBox2);        
            this.Controls.Add(this.groupBox1);        
            this.Name = "Form1";
            this.Text = "Form1";
            this.ResumeLayout(false);

        }

        #endregion

        private System.Windows.Forms.GroupBox groupBox1;
        private System.Windows.Forms.GroupBox groupBox2;
        private System.Windows.Forms.GroupBox groupBox3;
    }
}

        Winform中控件的叠加顺序同样取决于设计代码中调用Add方法的顺序。先Add的控件居于后Add的控件的上层

        也就是说,由上面的设计器代码可知: groupBox3 是位于顶层的,中间层是 groupBox2 ,而 groupBox1 位于底层。

        而 Dock 的填充顺序是从底层控件开始依次往上的,所以对于 Form1 来说:

  1. 最先设置 groupBox1 为 Top 没啥问题;
  2. 然后就是 Fill groupBox2 ,此时 groupBox2 就会填充整个窗体内除开 groupBox1 后剩余的所有空间
  3. 最后添加 groupBox3 为 Bottom ,当然就会覆盖住 groupBox2 的一部分内容了。 

        所以解决方法很简单:this.Controls.Add(this.groupBox2); 这句代码移动到 this.Controls.Add(this.groupBox3); 上面就可以了。

        当然,窗体设计器生成的代码是不推荐我们去动的,所以还是别动代码了;不过我们想修改这两句代码的先后顺序无非就是想改他俩的层次级别嘛,直接去设计窗口,右键点击 groupBox2 ,选择"置于顶层(B)"就好啦: 

        至于方案二中 groupBox1groupBox3 的层级关系就没那么重要啦~它们的 Dock 一个是Top、一个是Bottom,"井水不犯河水",谁也遮不了谁啦。 

        方案二调整后最终效果如图:

3、总结: 

  1. Winform窗体内控件的叠加顺序与我们设计时添加这些控件的顺序有关,设计时后添加的居于先添加的控件的上层;
    1. 以本文为例:我们设计时控件的添加顺序为 groupBox1 ==> groupBox2 ==> groupBox3 ;所以 groupBox2 居于 groupBox1 上层, groupBox3 居于 groupBox2 上层。 
  2. 控件的 Dock 填充顺序是从底层控件开始依次往上,上层控件会填充下层控件填充后剩余的空间;
  3. 当我们设置一个控件的 Dock 属性为 Fill ,只有当它是设计时最后一个被添加进来的控件(即位于顶层的控件)时才不会被其它的控件所遮盖;
Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐