劉逗逗逗逗逗 發表於 2026-4-5 19:18:00

基于.NET的Windows窗体编程之WinForms布局简介

<p>通过前两篇文章的学习,已经对基于.NET的Windows窗体编程有了初步认识,可以独立的创建应用程序。然而在实际应用开发中,软件能否吸引用户,除了实现必需的功能以外,UI布局设计也很重要,如整体风格,操作便捷性,以及符合大部分人的使用习惯等,合理的布局不仅可以有效利用空间,还能提高软件使用效率。今天我们主要介绍WinForm编程中的布局容器相关控件,仅供学习分享使用,如有不足之处,还请指正。</p>
<p><img src="https://img2024.cnblogs.com/blog/1068941/202603/1068941-20260329003445816-806777847.png"></p>
<p>&nbsp;</p>
<h1>布局容器概述</h1>
<p>&nbsp;</p>
<p>在WinForms框架中,容器控件都具有Controls属性,它表示一个Control实例的集合,通过此属性可以访问其包含的子控件。布局容器可以对控件进行明显的分组,那为什么要对控件进行分组呢?它主要有以下三个好处:</p>
<ul>
<li>为了实现清晰的用户界面,对相关表单元素进行视觉分组。</li>
<li>为了创建程序化分组(例如对单选按钮)。</li>
<li>用于在设计时将控件作为一个单元移动。</li>
</ul>
<p>&nbsp;</p>
<p>根据功能类型以及布局方式进行划分,布局容器控件主要有以下几种:</p>
<ul>
<li>Panel,用于分组和布局其他控件,支持滚动条。</li>
<li>GroupBox,带标题的容器,用于逻辑分组。</li>
<li>SplitContainer,可调整大小的分隔窗格,用于分栏布局。</li>
<li>TabControl,多标签页容器,切换不同内容区域。</li>
<li>FlowLayoutPanel,流式布局容器,自动排列子控件。</li>
<li>TableLayoutPanel,表格布局容器,支持行和列的定义。</li>
</ul>
<p>接下来将分别介绍各个容器控件,以及它们之间的异同之处。</p>
<p>&nbsp;</p>
<h1>GroupBox</h1>
<p>&nbsp;</p>
<p>GroupBox是一个带标题的分组控件,此控件用于为其他控件提供明显的分组,通常可以使用GroupBox按功能细分窗体。GroupBox关键属性:</p>
<ul>
<li>Text,用于设置GroupBox的标题。</li>
<li>Name,用于设置控件的唯一标识名称,它在当前窗体中唯一标识控件的能力。</li>
<li>Enable,用于设置容器控件是否启用,如果设置为否,则其子控件也会被置为不可用。</li>
<li>Visible,用于设置控件是否显示在Form窗体中。</li>
</ul>
<p>在Form窗体中添加GroupBox,和其他控件一样,可以从工具箱拖动一个GroupBox到Form窗体中,GoupBox作为容器控件,和其他普通单一功能控件一样,具备Size,Location等属性,可以用于设置大小,GoupBox的起始位置等信息。在本示例中,同一个Form窗体中,创建两个GroupBox,分别表示学生信息,班级信息,可以清晰的从视觉上进行区分,如下图所示:</p>
<p><img src="https://img2024.cnblogs.com/blog/1068941/202604/1068941-20260404165516994-519145366.gif"></p>
<p>&nbsp;</p>
<p>在上述示例中,学生信息GroupBox中的性别,用RadioButton进行表示,同时班级信息GroupBox中的放假,也用RadionButton进行表示,可以看出同一个GroupBox中的RadioButton是互斥的,如男/女,是/否只能有一个被选中;而分别处在两个GroupBox中的RadioButton则相互独立,互不干扰,如性别的选择,不会影响到放假的选择,这就是容器的另一个作用:程序化分组。</p>
<p>&nbsp;</p>
<p>如果GroupBox的Enable属性设置为False,则控件及其子控件均不可用,如下所示:</p>
<p><img src="https://img2024.cnblogs.com/blog/1068941/202604/1068941-20260404170630373-1212264125.png"></p>
<p>注意:GroupBox本身不包含滚动条,如果子控件的位置超过了GroupBox容器的大小,则会自动裁切。</p>
<p>&nbsp;</p>
<h1>Panel</h1>
<p>&nbsp;</p>
<p>Panel是一个不带标题的面板,此控件和GroupBox功能类似,主要用于为其他控件提供明显的分组。Panel控件的关键属性:</p>
<ul>
<li>AutoScroll属性,是否自动显示滚动条。若要显示滚动条,请将&nbsp;AutoScroll&nbsp;属性设置为&nbsp;<code>true</code></li>
<li>BackColor,背景色,设置所包含的控件的背景色,如标签和单选按钮。</li>
<li>BackgroundImage,背景图像,如果设置了该&nbsp;BackgroundImage&nbsp;属性,图像将显示在包含的控件后面。</li>
<li>BorderStyle,边框样式,它是一个枚举类型,主要有三个值:没有可见边框(None)、纯线(FixedSingle)或阴影线(Fixed3D)。</li>
</ul>
<p>&nbsp;</p>
<p>在Visual Studio中进行窗体设计时,Panel控件会有一个虚线边框,用于标识Panel控件的有效范围,如下所示:</p>
<p><img src="https://img2024.cnblogs.com/blog/1068941/202604/1068941-20260404171537413-851840343.png"></p>
<p>当实际运行起来时,是不带边框的,如下所示:</p>
<p><img src="https://img2024.cnblogs.com/blog/1068941/202604/1068941-20260404171706482-1867623478.png"></p>
<p>如果需要设置Panel容器的边框,可以设置BorderStyle属性,默认为None,表示无边框,设置为纯线(FixedSingle),效果如下所示:</p>
<p><img src="https://img2024.cnblogs.com/blog/1068941/202604/1068941-20260404172012741-1467319588.png"></p>
<p>如果Panel中子控件的位置大于Panel控件的大小,默认是会自动裁切,不显示滚动条;如果需要显示滚动条,则需要设置AutoScroll属性为true,如下所示:</p>
<p><img src="https://img2024.cnblogs.com/blog/1068941/202604/1068941-20260404172303913-791841122.png"></p>
<p>Panel控件设置背景色,同时会将背景色应用到其所包含的子控件中(如:Label,RadioButton,CheckBox等),如下所示:</p>
<p><img src="https://img2024.cnblogs.com/blog/1068941/202604/1068941-20260404172708766-522445710.png"></p>
<p>如果不想子控件和Panel容器控件背景色保持一致,则需要单独设置子个控件的背景色,如下所示:</p>
<p><img src="https://img2024.cnblogs.com/blog/1068941/202604/1068941-20260404173051819-1463160894.png"></p>
<p>注意:默认添加的Panel控件,是不自动填充到Form窗体中的,如过需要自动填充窗体,则需要设置Panel的Dock属性为Fill。</p>
<p>&nbsp;</p>
<h1 id="splitcontainer-control-windows-forms">SplitContainer</h1>
<p>&nbsp;</p>
<p>SplitContainer控件可以被视为一个组合控件,它由一个可移动条分隔成两个面板。 当鼠标指针位于条上时,指针的形状会改变,以指示该条是可移动的。此控件可以创建复杂的用户界面,如上下布局,左右布局等常见形式;SplitContainer关键属性如下所示:</p>
<ul>
<li>Orientation属性决定了拆分器的方向,当此属性设置为 Vertical时,拆分器从上到下运行,创建左右面板。</li>
<li>FixPanel属性确定在调整 SplitContainer控件大小后,哪个面板将保持固定大小。</li>
<li>IsSplitterFixed 属性确定拆分器是否可由键盘或鼠标移动。</li>
<li>SplitterDistance 属性确定从左边缘或上边缘到可移动拆分条之间的距离(以像素为单位)。</li>
<li>SplitterIncrement&nbsp;属性确定拆分器可由用户移动的最小距离(以像素为单位)。</li>
<li>SplitterWidth 属性确定拆分器宽(厚)度(以像素为单位)。</li>
<li>SplitterMoving 事件,拆分器移动时发生。</li>
<li>SplitterMoved&nbsp;事件,拆分器移动时发生。</li>
</ul>
<p>&nbsp;</p>
<p>在Form窗体中,默认添加的SplitContainer控件,会自动填充到当前Form窗体中,所以默认Dock属性为Fill。SplitContainer容器的默认Orientation属性为Vertical,创建左右布局,如下所示:</p>
<p><img src="https://img2024.cnblogs.com/blog/1068941/202604/1068941-20260404192740921-281616330.png"></p>
<p>如果需要创建上下布局,则可以设置Orientation属性为Horizantal。如下所示:</p>
<p><img src="https://img2024.cnblogs.com/blog/1068941/202604/1068941-20260404193016225-795186343.png"></p>
<p>容器控件之间可以进行嵌套,以实现复杂的布局,如:通过两个SplitContainer进行组合,便可以创建经典的上下左右布局,如下所示:</p>
<p><img src="https://img2024.cnblogs.com/blog/1068941/202604/1068941-20260404194133588-1750527516.png"></p>
<p>SpitContainer因其便利性,在众多布局容器中应用非常广泛。</p>
<p>&nbsp;</p>
<h1>TabControl</h1>
<p>&nbsp;</p>
<p>TabControl控件用于显示多个选项卡,就像笔记本中的分隔线或档案柜中一组文件夹的标签。 每个选项卡可以包含图片和其他控件。TabControl的关键属性:</p>
<ul>
<li>TabPages属性,是TabControl包含的子选项卡集合,每个单独的子选项卡都是一个&nbsp;TabPage&nbsp;对象。当单击选项卡时,它会为该Click对象引发TabPage事件。</li>
<li>&nbsp;SelectedIndexChanged 的事件,当用户从一个选项卡切换到下一个选项卡时引发的事件。</li>
</ul>
<p>在工具箱中,拖动TabControl控件到Form窗体中,便可以创建TabControl实例。默认创建的TabControl,并不会填充到Form窗体,如果需要填充整个窗体,可以设置Dock属性为Fill。在Visual Studio设计器中,可以点击TabControl右侧的箭头添加和删除选项卡,如下所示:</p>
<p><img src="https://img2024.cnblogs.com/blog/1068941/202604/1068941-20260404203010351-1693983448.gif"></p>
<p>除了上述方式,在选择TabControl实例后,通过属性窗口的TabPages集合编辑器窗口进行添加或删除选项卡,以及修改选项卡的属性等,如下所示:</p>
<p><img src="https://img2024.cnblogs.com/blog/1068941/202604/1068941-20260404203353780-1981033598.png"></p>
<p>通过TabPages选项卡编辑器,可以实现如下功能:</p>
<ol>
<li>添加,删除选项卡。</li>
<li>设置选项卡的属性,如Text属性对应TabControl控件中选项卡的标题</li>
<li>调整选项卡的顺序。</li>
</ol>
<p>当在TabControl的选项卡之间进行切换时,会触发SelectedIndexChanged事件,可以在此事件中处理需要的业务逻辑,如下所示:</p>
<p><img src="https://img2024.cnblogs.com/blog/1068941/202604/1068941-20260404204534081-1766929034.png"></p>
<p>如提示当前点击的选项卡的索引号,如下所示:</p>
<pre class="language-csharp highlighter-hljs"><code>namespace Okcoder.WinForm.Demo
{
    public partial class FrmTabControl : Form
    {
      public FrmTabControl()
      {
            InitializeComponent();
      }

      private void tabMain_SelectedIndexChanged(object sender, EventArgs e)
      {
            string msg = $"当前选择的是第{this.tabMain.SelectedIndex+1}个选项卡";
            MessageBox.Show(msg);
      }
    }
}</code></pre>
<p>示例效果如下所示:</p>
<p><img src="https://img2024.cnblogs.com/blog/1068941/202604/1068941-20260404204924537-559267982.gif"></p>
<p>&nbsp;</p>
<h1>FlowLayoutPanel</h1>
<p>&nbsp;</p>
<p>FlowLayoutPanel控件按水平或垂直流方向排列其内容。 它的内容可以从一行换到下一行,或从一列换到下一列。 或者,可以剪切其内容,而不是进行换行。</p>
<p>FlowLayoutPanel关键属性:</p>
<ul>
<li>FlowDirection 属性的值来指定流方向,此属性为枚举类型,共有4个选项:LeftToRight(从左到右),TopDown(从上到下),RightToLeft(从右到左),BottomUp(自底往上),默认为LeftToRight。</li>
<li>WrapContents 该值指示控件是 FlowLayoutPanel 应换行其内容还是允许剪裁内容,true表示换行,false表示裁切。</li>
<li>FlowBreak属性,FlowLayoutPanel的子控件因放置在FlowLayoutPanel容器中而具有的附加属性,用来设置是否终止当前流式布局,并从下一个控件新开启一行。</li>
</ul>
<p>FlowLayoutPanel采用流式布局方式,在一些特定场景下非常实用,FlowLayoutPanel的FlowDirection属性,默认为LeftToRight(左右),可以手动修改设置为TopToDown(上下),两种效果如下所示:</p>
<p><img src="https://img2024.cnblogs.com/blog/1068941/202604/1068941-20260404205934378-16193751.png"></p>
<p>如果WrapContents属性设置为false,则会裁切多余的内容,如下所示:</p>
<p><img src="https://img2024.cnblogs.com/blog/1068941/202604/1068941-20260404225305268-985722044.png"></p>
<p>在Visual Studio设计器中,FlowLayoutPanel会显示虚线边框,但是在运行起来后,默认并不显示边框。如果要显示边框,可以设置BorderStyle属性,具体可参考Panel设置边框。FlowLayoutPanel容器中的子控件会默认具有FlowBreak属性,默认为false,如果设置为true,则从当前控件中断流式布局,并从下一个控件新开启一行或列,如将第5个按钮的FlowBreak属性设置为true,效果如下所示:</p>
<p><img src="https://img2024.cnblogs.com/blog/1068941/202604/1068941-20260404230757297-175821615.png"></p>
<p>&nbsp;</p>
<h1>TableLayoutPanel</h1>
<p>&nbsp;</p>
<p>TableLayoutPanel 控件在网格中排列其内容。下面几个场景比较适合采用TableLayoutPanel进行布局:</p>
<ul>
<li>表单中有多个部分按比例调整大小的布局。</li>
<li>将在运行时动态修改或生成的布局,例如基于首选项添加或减去用户可自定义字段的数据输入表单。</li>
<li>应保持整体固定大小的布局。 例如,你可能有一个对话框应保持小于 800 x 600,但需要支持本地化字符串。</li>
</ul>
<p>&nbsp;</p>
<p>TableLayoutPanel的关键属性,如下所示:</p>
<ul>
<li>RowCount,获取或设置表中允许的最大行数。</li>
<li>ColumnCount,获取或设置表中允许的最大列数。</li>
</ul>
<p>首先在工具箱中,拖入TableLayoutPanel到Form窗体中,默认TableLayoutPanel是两行两列,可以通过控件右边的黑色实心三角,进行快捷添加和删除。在弹出的菜单中,点击“编辑行和列...”,可以打开“行和列样式”对话框,可以设置行列的宽度和高度,宽度高度设置可以有两种形式,如下所示:</p>
<ol>
<li>Percent:设置当前行/列占整个表格的百分比。</li>
<li>Absolute:绝对值,设置行/列的宽高像素值。</li>
<li>自动调整大小:根据内容自动调整大小,类似于自适应。</li>
</ol>
<p>具体设置方式如下图所示:</p>
<p><img src="https://img2024.cnblogs.com/blog/1068941/202604/1068941-20260404231601283-1939247563.gif"></p>
<p>默认情况下,TableLayoutPanel在Visual Studio设计器中显示虚线边框,实际运行起来并不显示,如果需要显示边框,可以设置CellBorderStyle属性,它是一个枚举值,主要有以下值:</p>
<ul>
<li>None,默认没有边框</li>
<li>Single,单一实线边框</li>
<li>Inset,单一实线下沉边框</li>
<li>InsetDouble,双实线下沉边框</li>
<li>Outset,单一实线凸起边框</li>
<li>OutsetDouble,双实线凸起边框</li>
<li>OutsetPartial,一条带有凸起部分的单线边框</li>
</ul>
<p>具体边框的不同值之间的效果,可以自行验证,设置为Single的效果如下所示:</p>
<p><img src="https://img2024.cnblogs.com/blog/1068941/202604/1068941-20260404233348688-1338426586.png"></p>
<p>通过拖动控件到TableLayoutPanel容器的指定单元格中,即可向容器中添加控件,添加到TableLayoutPanel容器中的控件,自动具有以上几个附加属性:</p>
<ul>
<li>Row,表示当前控件位于TableLayoutPanel的第几行。</li>
<li>Column,表示当前控件位于TableLayoutPanel的第几列。</li>
<li>RowSpan,表示当前控件在TableLayoutPanel中占几行,如果子控件太大,一行不够,可以修改RowSpan属性,合并行。</li>
<li>ColumnSpan,表示当前控件在TableLayoutPanel中占几列,如果子控件太大,一列不够,可以修改ColumnSpan属性,合并列。</li>
</ul>
<p>三个按钮分别位于(0,0),(1,1),(2,2)位置,效果如下图所示:</p>
<p><img src="https://img2024.cnblogs.com/blog/1068941/202604/1068941-20260404234336515-1591405184.png"></p>
<p>以上就是《基于.NET的Windows窗体编程之WinForms布局简介》的全部内容,旨在抛砖引玉,一起学习,共同进步。</p>

</div>
<div id="MySignature" role="contentinfo">
    <div id="AllanboltSignature">

    <p style="border-top: #e0e0e0 1px dashed; border-right: #e0e0e0 1px dashed; border-bottom: #e0e0e0 1px dashed; border-left: #e0e0e0 1px dashed; padding-top: 10px; padding-right: 10px; padding-bottom: 10px; padding-left: 30px; font-family: 微软雅黑; font-size: 12px" id="PSignature">
<br>

   <img alt="" src="https://images.cnblogs.com/cnblogs_com/hsiang/1154298/o_115f1cd8.jpg" width="80px" height="80px">
   
    作者:老码识途
    <br>
    出处:http://www.cnblogs.com/hsiang/
    <br>
    本文版权归作者和博客园共有,写文不易,支持原创,欢迎转载【点赞】,转载请保留此段声明,且在文章页面明显位置给出原文连接,谢谢。
    <br>关注个人公众号,定时同步更新技术及职场文章
<br><br>
   </p>
</div><br><br>
来源:https://www.cnblogs.com/hsiang/p/19804144
頁: [1]
查看完整版本: 基于.NET的Windows窗体编程之WinForms布局简介