WPF 核心布局控件全解析:从 Grid 到 UniformGrid 的实战应用

【WPF应用7】 基本控件-Grid 布局的详解与示例 WPF 基本控件-Grid布局的详解与示例 阅读详情

WPF 布局的核心是容器控件通过规则划分空间,子元素依附容器规则排列。以下结合你提供的示例,系统梳理 Grid、StackPanel、WrapPanel、DockPanel、UniformGrid 的核心特性、用法和差异。

一、Grid:最灵活的网格布局(WPF 布局基石)

Grid 是 WPF 最核心的布局控件,通过行(RowDefinitions) 和 列(ColumnDefinitions) 将空间划分为二维网格,支持自定义尺寸、跨行列,是绝大多数 WPF 界面的基础容器。

1. Grid 核心规则:行高 / 列宽的 3 种定义方式

Grid 的行高(Height)和列宽(Width)是其核心,支持三种核心定义方式,决定了网格空间的分配逻辑:

定义方式实际含义设计层面的理解
Auto以子元素 DesiredSize 为准内容驱动布局
*在剩余空间中按比例分配区域驱动布局
固定值像素级锁定视觉约束

2. Grid 实战示例解析

(1)基础 2 行 2 列均分布局

这是 Grid 最基础的用法,未指定行高 / 列宽时,所有行 / 列按 1:1 比例均分空间:

<!-- 
Grid(网格布局)是WPF中最常用的布局控件之一
可以通过行(RowDefinitions)和列(ColumnDefinitions)将空间划分为网格状
-->
<Grid>
  <!-- 定义Grid的行集合:这里定义了2行 -->
  <Grid.RowDefinitions>
    <!-- 单个行定义,未指定Height时默认均分空间(即每行占窗口高度的50%) -->
    <RowDefinition />
    <RowDefinition/>
  </Grid.RowDefinitions>

  <!-- 定义Grid的列集合:这里定义了2列 -->
  <Grid.ColumnDefinitions>
    <!-- 单个列定义,未指定Width时默认均分空间(即每列占窗口宽度的50%) -->
    <ColumnDefinition />
    <ColumnDefinition/>
  </Grid.ColumnDefinitions>

  <!-- 第一行第一列(索引从0开始)放置红色背景的Border控件 -->
  <Border Grid.Row="0" Grid.Column="0" Background="Red" />
  <!-- 第一行第二列放置黄色背景的Border控件 -->
  <Border Grid.Row="0" Grid.Column="1" Background="Yellow" />
  <!-- 第二行第一列放置蓝色背景的Border控件 -->
  <Border Grid.Row="1" Grid.Column="0" Background="Blue" />
  <!-- 第二行第二列放置绿色背景的Border控件 -->
  <Border Grid.Row="1" Grid.Column="1" Background="Green" />
</Grid>

image


效果: 4 个 Border 各占 Grid 空间的 1/4,行高、列宽均为容器的 50%。

(2)auto 行高:适配内容尺寸

将第一行高度设为auto,行高会跟随内部子元素的高度变化(如子元素是 100 高的按钮,行高自动为 100):

<!-- 
    Grid(网格布局)是WPF中最常用的布局控件之一
    可以通过行(RowDefinitions)和列(ColumnDefinitions)将空间划分为网格状
-->
<Grid>
    <!-- 定义Grid的行集合:这里定义了2行 -->
    <Grid.RowDefinitions>
        <!-- 单个行定义,未指定Height时默认均分空间(即每行占窗口高度的50%) -->
        <RowDefinition Height="auto"/>
        <!-- 重点改了!第一行高度设为auto -->
        <RowDefinition/>
        <!-- 第二行没设Height,默认*比例 -->
    </Grid.RowDefinitions>

    <!-- 定义Grid的列集合:这里定义了2列 -->
    <Grid.ColumnDefinitions>
        <!-- 单个列定义,未指定Width时默认均分空间(即每列占窗口宽度的50%) -->
        <ColumnDefinition />
        <ColumnDefinition/>
    </Grid.ColumnDefinitions>

    <!-- 第一行第一列(索引从0开始)放置红色背景的Border控件 -->
    <Border Grid.Row="0" Grid.Column="0" Background="Red" />
    <!-- 第一行第二列放置黄色背景的Border控件 -->
    <Border Grid.Row="0" Grid.Column="1" Background="Yellow" />
    <!-- 第二行第一列放置蓝色背景的Border控件 -->
    <Border Grid.Row="1" Grid.Column="0" Background="Blue" />
    <!-- 第二行第二列放置绿色背景的Border控件 -->
    <Border Grid.Row="1" Grid.Column="1" Background="Green" />
</Grid>

image


效果: 第一行高度由内部 Border 的高度决定(无固定尺寸时仅占内容最小高度),第二行占满剩余所有空间。
添加一个按钮高度是100 ,那么第一行默认为100

image

(3)固定行高:精准控制尺寸

将第一行高度设为固定值100,行高不再随内容或容器变化,始终保持 100 像素:

    <!-- 
        Grid(网格布局)是WPF中最常用的布局控件之一
        可以通过行(RowDefinitions)和列(ColumnDefinitions)将空间划分为网格状
    -->
    <Grid>
        <!-- 定义Grid的行集合:这里定义了2行 -->
        <Grid.RowDefinitions>
            <!-- 单个行定义,未指定Height时默认均分空间(即每行占窗口高度的50%) -->
            <RowDefinition Height="100"/>
            <!-- 重点改了!第一行高度设为100 -->
            <RowDefinition/>
            <!-- 第二行没设Height,默认*比例 -->
        </Grid.RowDefinitions>

        <!-- 定义Grid的列集合:这里定义了2列 -->
        <Grid.ColumnDefinitions>
            <!-- 单个列定义,未指定Width时默认均分空间(即每列占窗口宽度的50%) -->
            <ColumnDefinition />
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>

        <!-- 第一行第一列(索引从0开始)放置红色背景的Border控件 -->
        <Border Grid.Row="0" Grid.Column="0" Background="Red" />
        <!-- 第一行第二列放置黄色背景的Border控件 -->
        <Border Grid.Row="0" Grid.Column="1" Background="Yellow" />
        <!-- 第二行第一列放置蓝色背景的Border控件 -->
        <Border Grid.Row="1" Grid.Column="0" Background="Blue" />
        <!-- 第二行第二列放置绿色背景的Border控件 -->
        <Border Grid.Row="1" Grid.Column="1" Background="Green" />
    </Grid>

image

(4)比例行高(n*):按比例分配空间

将第一行高度设为2,第二行默认1,两行按 2:1 的比例瓜分 Grid 的总高度:

<!-- 
    Grid(网格布局)是WPF中最常用的布局控件之一
    可以通过行(RowDefinitions)和列(ColumnDefinitions)将空间划分为网格状
-->
<Grid>
    <!-- 定义Grid的行集合:这里定义了2行 -->
    <Grid.RowDefinitions>
        <!-- 单个行定义,未指定Height时默认均分空间(即每行占窗口高度的50%) -->
        <RowDefinition Height="2*"/>
        <!-- 重点改了!第一行高度设为2* -->
        <RowDefinition/>
        <!-- 第二行没设Height,默认*比例 -->
    </Grid.RowDefinitions>

    <!-- 定义Grid的列集合:这里定义了2列 -->
    <Grid.ColumnDefinitions>
        <!-- 单个列定义,未指定Width时默认均分空间(即每列占窗口宽度的50%) -->
        <ColumnDefinition />
        <ColumnDefinition/>
    </Grid.ColumnDefinitions>

    <!-- 第一行第一列(索引从0开始)放置红色背景的Border控件 -->
    <Border Grid.Row="0" Grid.Column="0" Background="Red" />
    <!-- 第一行第二列放置黄色背景的Border控件 -->
    <Border Grid.Row="0" Grid.Column="1" Background="Yellow" />
    <!-- 第二行第一列放置蓝色背景的Border控件 -->
    <Border Grid.Row="1" Grid.Column="0" Background="Blue" />
    <!-- 第二行第二列放置绿色背景的Border控件 -->
    <Border Grid.Row="1" Grid.Column="1" Background="Green" />
</Grid>

image

(5)跨行列布局:RowSpan/ColumnSpan

通过RowSpan(跨行)、ColumnSpan(跨列),可让子元素占据多个网格区域:
跨2列

<!-- 
    Grid(网格布局):WPF中最核心、最灵活的布局控件
    核心能力:通过RowDefinitions(行集合)和ColumnDefinitions(列集合)将容器划分为网格状区域
    每个控件可通过Grid.Row/Grid.Column指定放置的网格位置,还能通过RowSpan/ColumnSpan跨行列
-->
<Grid>
    <!-- 定义Grid的行集合:共定义2行 -->
    <Grid.RowDefinitions>
        <!-- RowDefinition未指定Height时,默认值为"*"(比例分配) -->
        <RowDefinition/>
        <!-- 第0行:高度占比1*,无显式Height则默认均分 -->
        <RowDefinition/>
        <!-- 第1行:高度占比1*,两行比例1:1,各占Grid高度的50% -->
    </Grid.RowDefinitions>

    <!-- 定义Grid的列集合:共定义2列 -->
    <Grid.ColumnDefinitions>
        <!-- ColumnDefinition未指定Width时,默认值为"*"(比例分配) -->
        <ColumnDefinition />
        <!-- 第0列:宽度占比1* -->
        <ColumnDefinition/>
        <!-- 第1列:宽度占比1*,两列比例1:1,各占Grid宽度的50% -->
    </Grid.ColumnDefinitions>

    <!-- Border控件布局说明:
         1. 未指定Grid.Row,默认放置在第0行;
         2. Grid.ColumnSpan="2":表示该控件跨2列显示(同时占据第0列和第1列);
         3. Background="Red":设置控件背景色为红色
    -->
    <Border Grid.ColumnSpan="2" Background="Red" />

</Grid>

image


跨2行

<Grid>
    <!-- 定义Grid的行集合:共定义2行 -->
    <Grid.RowDefinitions>
        <!-- RowDefinition未指定Height时,默认值为"*"(比例分配) -->
        <RowDefinition/>
        <!-- 第0行:高度占比1*,无显式Height则默认均分 -->
        <RowDefinition/>
        <!-- 第1行:高度占比1*,两行比例1:1,各占Grid高度的50% -->
    </Grid.RowDefinitions>

    <!-- 定义Grid的列集合:共定义2列 -->
    <Grid.ColumnDefinitions>
        <!-- ColumnDefinition未指定Width时,默认值为"*"(比例分配) -->
        <ColumnDefinition />
        <!-- 第0列:宽度占比1* -->
        <ColumnDefinition/>
        <!-- 第1列:宽度占比1*,两列比例1:1,各占Grid宽度的50% -->
    </Grid.ColumnDefinitions>

    <!-- Border控件布局说明:
         1. 未指定Grid.Row,默认放置在第0行;
         2. Grid.ColumnSpan="2":表示该控件跨2列显示(同时占据第0列和第1列);
         3. Background="Red":设置控件背景色为红色
    -->
    <Border Grid.RowSpan="2" Background="Red" />

</Grid>

image

3. Grid 注意事项

  • 行 / 列索引从 0 开始,子元素未指定Grid.Row/Grid.Column时,默认放在第 0 行第 0 列;
  • auto行 / 列会优先占用空间,剩余空间才会分配给*行 / 列;
  • 跨行列元素会覆盖对应网格区域,需注意布局层级与重叠问题。

二、StackPanel:线性堆栈布局(简单高效的单行 / 列排列)

StackPanel 是 WPF 中最简洁的线性布局控件,子元素沿Orientation指定的方向(垂直 / 水平)依次堆叠,适合固定数量的单行 / 列元素排列。

1. StackPanel 核心特性

  • 排列方向:Orientation="Vertical"(默认,垂直堆叠)/Orientation="Horizontal"(水平堆叠);
  • 超出处理:子元素总尺寸超出容器时,无滚动条,超出部分直接隐藏;
  • 尺寸适配:若父容器行高为*(非 auto),StackPanel 会在容器中居中显示。

2. StackPanel 实战示例

(1)垂直堆叠:7 个固定尺寸按钮
<!-- ===================== Grid网格布局核心说明 ===================== -->
<!-- Grid是WPF最灵活的布局控件,通过「行(Row)」和「列(Column)」将空间划分为网格 -->
<!-- 所有直接子元素可通过Grid.Row/Grid.Column指定所在行列(默认都在第0行第0列) -->
<Grid>

    <!-- ===================== 定义Grid的行集合 ===================== -->
    <Grid.RowDefinitions>
        <!-- 第0行:Height="auto" 表示行高「自适应内容高度」,内容多高行就多高 -->
        <RowDefinition Height="auto"/>

        <!-- 第1行:未指定Height,默认值为"*"(星号),表示「占满剩余所有空间」 -->
        <!-- 因为第0行是auto,所以第1行高度 = 窗口总高度 - 第0行内容高度 -->
        <RowDefinition/>
    </Grid.RowDefinitions>

    <!-- ===================== 定义Grid的列集合 ===================== -->
    <Grid.ColumnDefinitions>
        <!-- 第0列:未指定Width,默认值为"*",表示「均分可用宽度」 -->
        <ColumnDefinition />

        <!-- 第1列:同理第0列,两列无特殊指定时,各占Grid总宽度的50% -->
        <ColumnDefinition/>
    </Grid.ColumnDefinitions>

    <!-- ===================== StackPanel堆栈布局 ===================== -->
    <!-- StackPanel是「线性布局控件」,默认垂直(Vertical)堆叠所有子元素 -->
    <!-- 该StackPanel未指定Grid.Row/Grid.Column,默认放在Grid的第0行第0列 -->
    <StackPanel>
        <!-- 多个固定宽高的按钮,StackPanel会垂直依次排列 -->
        <!-- 按钮超出StackPanel可视区域时,默认无滚动条,超出部分会被隐藏 -->
        <Button Width="100" Height="40" >按钮1</Button>
        <Button Width="100" Height="40" >按钮2</Button>
        <Button Width="100" Height="40" >按钮3</Button>
        <Button Width="100" Height="40" >按钮4</Button>
        <Button Width="100" Height="40" >按钮5</Button>
        <Button Width="100" Height="40" >按钮6</Button>
        <Button Width="100" Height="40" >按钮7</Button>
    </StackPanel>

</Grid>

image

(2)水平堆叠:7 个固定尺寸按钮
<Window
    x:Class="_01.WPF布局基础.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:_01.WPF布局基础"
    mc:Ignorable="d"
    Title="MainWindow" Height="450" Width="800">

    <!-- 核心布局容器:Grid(网格布局) -->
    <!-- 作用:将容器空间按「行+列」划分为二维网格,是WPF最常用、最灵活的布局控件 -->
    <!-- 子元素可通过Grid.Row/Grid.Column附加属性指定所在行列(默认都在第0行第0列) -->
    <Grid>

        <!-- 定义Grid的行集合(RowDefinitions) -->
        <!-- 每行通过RowDefinition定义,Height属性控制行高规则 -->
        <Grid.RowDefinitions>
            <!-- 第0行:Height="auto" -->
            <!-- 规则:行高自适应子元素的实际高度,子元素多高,行就多高 -->
            <RowDefinition Height="auto"/>

            <!-- 第1行:未显式指定Height(默认值为"*") -->
            <!-- 规则:"*"表示占满容器剩余的所有空间 -->
            <!-- 实际高度 = Grid总高度 - 第0行的实际高度 -->
            <RowDefinition/>
        </Grid.RowDefinitions>

        <!-- 定义Grid的列集合(ColumnDefinitions) -->
        <!-- 每列通过ColumnDefinition定义,Width属性控制列宽规则 -->
        <Grid.ColumnDefinitions>
            <!-- 第0列:未显式指定Width(默认值为"*") -->
            <!-- 规则:"*"表示按比例均分可用宽度 -->
            <ColumnDefinition />

            <!-- 第1列:未显式指定Width(默认值为"*") -->
            <!-- 效果:与第0列均分Grid总宽度,各占50% -->
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>

        <!-- 子布局控件:StackPanel(堆栈布局) -->
        <!-- 作用:将子元素按线性方向(水平/垂直)依次排列 -->
        <!-- 位置:未指定Grid.Row/Grid.Column,默认在Grid第0行第0列 -->
        <StackPanel 
            <!-- Orientation:排列方向,Horizontal=水平排列,Vertical=垂直排列(默认) -->
            Orientation="Horizontal">

            <!-- StackPanel子元素:多个固定尺寸的按钮 -->
            <!-- 布局特点:水平依次排列,超出StackPanel可视区域时,超出部分会被隐藏(无滚动条) -->
            <Button Width="100" Height="40" >按钮1</Button>
            <Button Width="100" Height="40" >按钮2</Button>
            <Button Width="100" Height="40" >按钮3</Button>
            <Button Width="100" Height="40" >按钮4</Button>
            <Button Width="100" Height="40" >按钮5</Button>
            <Button Width="100" Height="40" >按钮6</Button>
            <Button Width="100" Height="40" >按钮7</Button>
        </StackPanel>

    </Grid>
</Window>

image

3. 关键优化:去掉 auto 行高实现居中

若将 Grid 第 0 行的Height="auto"改为默认*,StackPanel 会在占满行高的 Grid 中水平居中显示:

<Grid>
  <Grid.RowDefinitions>
    <RowDefinition /> <!-- 去掉auto,默认* -->
    <RowDefinition/>
  </Grid.RowDefinitions>
  <Grid.ColumnDefinitions>
    <ColumnDefinition />
    <ColumnDefinition/>
  </Grid.ColumnDefinitions>
  <StackPanel Orientation="Horizontal">
    <!-- 按钮列表 -->
  </StackPanel>
</Grid>

image

三、WrapPanel:自动换行布局(StackPanel 增强版)

WrapPanel 继承了 StackPanel 的线性排列逻辑,但解决了 “超出隐藏” 的问题 —— 子元素超出容器宽度(水平)/ 高度(垂直)时,会自动换行 / 换列,适合动态数量的元素布局(如标签云、按钮列表)。

1. StackPanel vs WrapPanel 对比示例

特性StackPanelWrapPanel
超出处理隐藏超出部分自动换行 / 列
空间利用率低(仅沿单方向排列)高(自动填充多行 / 列)
适用场景固定数量、单行 / 列元素动态数量、需自适应换行元素
<!-- ===================== Grid网格布局核心说明 ===================== -->
<!-- Grid是WPF最灵活的布局控件,通过「行(Row)」和「列(Column)」将空间划分为网格 -->
<!-- 所有直接子元素可通过Grid.Row/Grid.Column指定所在行列(默认都在第0行第0列) -->
<Grid>

    <!-- ===================== 定义Grid的行集合 ===================== -->
    <Grid.RowDefinitions>
        <!-- 第0行:Height="auto" 表示行高「自适应内容高度」,内容多高行就多高 -->
        <RowDefinition />

        <!-- 第1行:未指定Height,默认值为"*"(星号),表示「占满剩余所有空间」 -->
        <!-- 因为第0行是auto,所以第1行高度 = 窗口总高度 - 第0行内容高度 -->
        <RowDefinition/>
    </Grid.RowDefinitions>

    <!-- ===================== 定义Grid的列集合 ===================== -->
    <Grid.ColumnDefinitions>
        <!-- 第0列:未指定Width,默认值为"*",表示「均分可用宽度」 -->
        <ColumnDefinition />

        <!-- 第1列:同理第0列,两列无特殊指定时,各占Grid总宽度的50% -->
        <ColumnDefinition/>
    </Grid.ColumnDefinitions>

    <!-- ===================== StackPanel堆栈布局 ===================== -->
    <!-- StackPanel是「线性布局控件」,默认垂直(Vertical)堆叠所有子元素 -->
    <!-- 该StackPanel未指定Grid.Row/Grid.Column,默认放在Grid的第0行第0列 -->
    <StackPanel Orientation="Horizontal">
        <!-- 多个固定宽高的按钮,StackPanel会垂直依次排列 -->
        <!-- 按钮超出StackPanel可视区域时,默认无滚动条,超出部分会被隐藏 -->
        <Button Width="100" Height="40" >按钮1</Button>
        <Button Width="100" Height="40" >按钮2</Button>
        <Button Width="100" Height="40" >按钮3</Button>
        <Button Width="100" Height="40" >按钮4</Button>
        <Button Width="100" Height="40" >按钮5</Button>
        <Button Width="100" Height="40" >按钮6</Button>
        <Button Width="100" Height="40" >按钮7</Button>
    </StackPanel>

    <!-- ===================== 子布局2:WrapPanel(自动换行布局) ===================== -->
    <!-- WrapPanel:线性布局的增强版,子元素超出容器宽度/高度时自动换行/换列 -->
    <!-- Grid.Row="1":指定该WrapPanel放在Grid的第1行(默认第0列) -->
    <!-- 特性:相比StackPanel不会隐藏超出内容,而是自动换行,更适合动态数量的元素布局 -->
    <WrapPanel Grid.Row="1">
        <Button Width="100" Height="40" >按钮1</Button>
        <Button Width="100" Height="40" >按钮2</Button>
        <Button Width="100" Height="40" >按钮3</Button>
        <Button Width="100" Height="40" >按钮4</Button>
        <Button Width="100" Height="40" >按钮5</Button>
        <Button Width="100" Height="40" >按钮6</Button>
        <Button Width="100" Height="40" >按钮7</Button>
    </WrapPanel>

</Grid>

image


效果:StackPanel 的按钮超出容器宽度后隐藏,而 WrapPanel 会自动换行,所有按钮都能显示。

四、DockPanel:停靠布局(窗体框架首选)

DockPanel 让子元素沿Top/Bottom/Left/Right方向停靠,剩余空间由最后一个子元素填充(可通过LastChildFill关闭),是搭建窗体框架(顶部导航、底部状态栏、侧边栏)的首选。

1. DockPanel 核心规则

  • 停靠顺序决定布局:先停靠的元素优先占用空间,后停靠的元素在剩余空间内停靠;
  • LastChildFill:默认True,最后一个子元素填充剩余空间;设为False则仅显示手动停靠的元素;
  • 正确停靠逻辑:先停靠Top/Bottom(纵向),再停靠Left/Right(横向),避免空间挤压。

2. DockPanel 实战示例

 <Grid>

     <!-- ===================== 定义Grid的行集合(RowDefinitions) ===================== -->
     <!-- Grid的行通过RowDefinitions集合定义,每行对应一个RowDefinition对象 -->
     <Grid.RowDefinitions>
         <!-- 第0行:未显式指定Height,默认值为Auto(自适应内容高度) -->
         <!-- Auto特性:行高由该行内子元素的实际高度决定(内容多高,行就多高) -->
         <RowDefinition />

         <!-- 第1行:未显式指定Height,默认值为"*"(星号,比例分配) -->
         <!-- "*"特性:占据Grid剩余的所有空间(此处 = 窗口总高度 - 第0行高度 - 第2行高度 - 第3行高度) -->
         <!-- 若多个行都设为"*",则按1:1:1比例分配剩余空间 -->
         <RowDefinition/>
         <RowDefinition/>
         <RowDefinition/>
     </Grid.RowDefinitions>

     <!-- ===================== 第一个DockPanel(默认配置) ===================== -->
     <!-- DockPanel:停靠布局控件,核心逻辑是「子元素沿指定方向停靠,剩余空间由最后一个子元素填充」 -->
     <!-- 未指定Grid.Row/Grid.Column,默认放在Grid的第0行第0列(Grid默认只有1列) -->
     <DockPanel >
         <!-- DockPanel核心默认属性:LastChildFill="True"(最后一个子元素自动填充剩余空间) -->
         <!-- 子元素未指定DockPanel.Dock时,默认Dock="Left"(向左停靠) -->
         <!-- 效果:4个按钮依次向左水平排列,最后一个按钮(按钮4)会填充剩余宽度(因LastChildFill=True) -->
         <Button Width="100" Height="40" >按钮1</Button>
         <Button Width="100" Height="40" >按钮2</Button>
         <Button Width="100" Height="40" >按钮3</Button>
         <Button Width="100" Height="40" >按钮4</Button>
     </DockPanel>

     <!-- ===================== 第二个DockPanel(关闭LastChildFill) ===================== -->
     <!-- Grid.Row="1":指定该DockPanel放在Grid的第1行(列默认第0列) -->
     <!-- LastChildFill="False":关闭「最后一个子元素填充剩余空间」特性 -->
     <DockPanel Grid.Row="1" LastChildFill="False">
         <!-- 所有按钮未指定Dock属性,默认Dock="Left"(向左停靠),宽度固定100 -->
         <!-- 关键逻辑:LastChildFill="False"时,所有子元素都保持自身尺寸,不会填充剩余空间 -->
         <!-- 边界情况:若子元素总宽度(4*100=400)≤DockPanel宽度(窗口宽度800),则全部显示;若超出则超出部分隐藏 -->
         <Button Width="100" Height="40" >按钮1</Button>
         <Button Width="100" Height="40" >按钮2</Button>
         <Button Width="100" Height="40" >按钮3</Button>
         <Button Width="100" Height="40" >按钮4</Button>
     </DockPanel>

     <!-- ===================== 第三个DockPanel(混合停靠方向:布局反例) ===================== -->
     <!-- Grid.Row="2":放在Grid第2行 -->
     <!-- 核心问题:停靠顺序错误(先横向Left/Right,再纵向Top/Bottom),导致布局挤压 -->
     <!-- 逻辑缺陷:
          1. 先停靠Left(按钮1)→ 占据左侧100宽度
          2. 再停靠Top(按钮2)→ 只能在按钮1右侧的剩余空间里“顶部停靠”,宽度被挤压
          3. 再停靠Right(按钮3)→ 在按钮2下方的剩余空间里“右侧停靠”,高度被挤压
          4. 最后停靠Bottom(按钮4)→ 空间被严重压缩,显示异常
     -->
     <DockPanel Grid.Row="2" LastChildFill="False">
         <Button Width="100" Height="40" DockPanel.Dock="Left" >按钮1</Button>
         <!-- 先左停靠 -->
         <Button Width="100" Height="40" DockPanel.Dock="Top" >按钮2</Button>
         <!-- 再上停靠(被左按钮挤压) -->
         <Button Width="100" Height="40" DockPanel.Dock="Right" >按钮3</Button>
         <!-- 再右停靠(被上下按钮挤压) -->
         <Button Width="100" Height="40" DockPanel.Dock="Bottom" >按钮4</Button>
         <!-- 最后下停靠(空间不足) -->
     </DockPanel>

     <!-- ===================== 第四个DockPanel(修正版:正确的停靠逻辑) ===================== -->
     <!-- Grid.Row="3":放在Grid第3行 -->
     <!-- LastChildFill="False":关闭自动填充(仅保留手动停靠的元素) -->
     <!-- Background="#F0F0F0":浅灰色背景,便于观察DockPanel的边界 -->
     <!-- 核心原则:DockPanel停靠顺序决定布局 → 先停靠「纵向(Top/Bottom)」,再停靠「横向(Left/Right)」 -->
     <!-- 正确逻辑:
          1. 先停靠Top/Bottom:占据完整的上下边缘(无横向挤压,因为纵向停靠优先占满整行宽度)
          2. 再停靠Left/Right:在上下按钮之间的剩余空间里,占据左右边缘(无纵向挤压)
     -->
     <DockPanel Grid.Row="3" LastChildFill="False" Background="#F0F0F0">
         <!-- 第一步:先停靠纵向(Top/Bottom)→ 占满整行宽度,无横向挤压 -->
         <!-- HorizontalAlignment="Center":按钮水平居中(默认是Stretch,此处手动居中更美观) -->
         <Button Width="100" Height="40" DockPanel.Dock="Top" Content="按钮2(上)" 
                 HorizontalAlignment="Center"/>
         <!-- 顶部停靠 + 水平居中 -->
         <Button Width="100" Height="40" DockPanel.Dock="Bottom" Content="按钮4(下)" 
                 HorizontalAlignment="Center"/>
         <!-- 底部停靠 + 水平居中 -->

         <!-- 第二步:再停靠横向(Left/Right)→ 在上下按钮之间的剩余空间里占左右边缘 -->
         <!-- VerticalAlignment="Center":按钮垂直居中(默认是Stretch,此处手动居中更美观) -->
         <Button Width="100" Height="100" DockPanel.Dock="Left" Content="按钮1(左)" 
                 VerticalAlignment="Center"/>
         <!-- 左侧停靠 + 垂直居中 -->
         <Button Width="100" Height="100" DockPanel.Dock="Right" Content="按钮3(右)" 
                 VerticalAlignment="Center"/>
         <!-- 右侧停靠 + 垂直居中 -->
     </DockPanel>
 </Grid>

image


效果:示例 4 的布局规整无挤压,是 DockPanel 的标准用法;示例 3 因停靠顺序错误,元素空间被严重挤压,显示异常。

五、UniformGrid:均匀网格布局(等分空间神器)

UniformGrid 是 Grid 的简化版,无需手动定义行 / 列尺寸,自动将空间平均分配给所有单元格,所有单元格尺寸完全相同,适合 “等分空间” 场景(如计算器按钮、九宫格、键盘按键)。

1. UniformGrid 核心属性

  • Columns:指定列数;
  • Rows:指定行数;
  • 特性:子元素自动填充单元格,数量不足时剩余单元格为空,数量过多时自动换行 / 列。

2. UniformGrid 实战示例

<!-- 
        布局说明:
        1. Grid是WPF最基础的布局控件(网格布局),支持自定义行/列划分
        2. UniformGrid是Grid的简化版(均匀网格),自动将空间平均分配给子元素,
           无需手动定义行/列尺寸,适合需要"等分空间"的场景(如计算器按钮、九宫格等)
    -->
    <Grid>
        <!-- 
            UniformGrid属性说明:
            - Columns:设置列数(此处为4列)
            - Rows:设置行数(此处为3行)
            - 特性:所有单元格尺寸完全相同,子元素会自动填充到单元格中,
              即使子元素数量少于单元格总数,剩余单元格为空;若多于则自动换行/列
        -->
        <UniformGrid Columns="4" Rows="3">
            <!-- 子元素:Button按钮(共9个,填充4列3行的12个单元格中的前9个) -->
            <Button Content="按钮1"/> <!-- 补充Content属性,便于可视化 -->
            <Button Content="按钮2"/>
            <Button Content="按钮3"/>
            <Button Content="按钮4"/>
            <Button Content="按钮5"/>
            <Button Content="按钮6"/>
            <Button Content="按钮7"/>
            <Button Content="按钮8"/>
            <Button Content="按钮9"/>
        </UniformGrid>
    </Grid>

image


效果: 4 列 3 行共 12 个单元格,9 个按钮填充前 9 个,每个单元格尺寸 = 容器宽度 / 4、容器高度 / 3,完全均分。

六、核心布局控件选型指

控件核心优势核心劣势适用场景
Grid灵活、支持自定义行 / 列、跨行列配置稍复杂复杂界面(窗体、表单、多模块布局)
StackPanel简单、线性排列超出隐藏、无自动换行固定数量单行 / 列元素(导航栏、列表项)
WrapPanel自动换行、适配动态元素无法精准控制位置动态数量元素(标签云、按钮列表)
DockPanel按方向停靠、布局规整依赖停靠顺序、易挤压窗体框架(顶部导航、底部状态栏、侧边栏)
UniformGrid均分空间、配置简单无法自定义单元格尺寸等分布局(计算器、九宫格、键盘按键)

七、总结

  1. WPF 布局的核心是 “容器规则 + 子元素适配”,掌握以下要点可快速搭建高质量界面:
  2. 优先用 Grid 作为根容器,嵌套其他布局控件实现复杂布局;
  3. StackPanel 适合简单线性排列,WrapPanel 适配动态元素换行;
  4. DockPanel 搭建窗体框架时,务必遵循 “先纵向(Top/Bottom)、后横向(Left/Right)” 的停靠顺序;
  5. UniformGrid 是等分空间的最优解,无需手动计算比例;
  6. 行 / 列尺寸优先用*(比例)和auto(自适应),固定值仅用于精准控制的场景。

通过灵活组合这些布局控件,可兼顾 WPF 界面的 “自适应” 与 “美观性”,满足从简单按钮列表到复杂业务窗体的所有布局需求。

image

WPF的布局核心:网格布局(Grid) 本文详细介绍了WPF中的Grid网格布局系统,主要包括以下核心内容:1)三种行列尺寸定义方式(Auto/*/固定值)及其应用场景;2)元素定位与跨行跨列合并的实现;3)高级技巧如共享尺寸组和动态布局;4)通过邮件客户端案例展示嵌套布局实践。文章还提供了常见问题排查指南,帮助开发者掌握这个最强大的二维布局控件,以构建复杂的界面结构。建议通过表格布局、响应式设计等场景进行实践练习。 阅读详情

相关推荐

C# WPF入门学习主线篇(十六)—— Grid布局容器

在《C# WPF入门学习主线篇(十六)—— Grid布局容器》这篇文章中,我们详细介绍了WPF中的 `Grid` 布局容器。本文涵盖了 `Grid` 的基本概念、常见属性及使用方法,并通过具体的示例代码展示了如何实现复杂且灵活的用户界面布局。此外,还讨论了 `Grid` 布局容器的优缺点,帮助读者在实际开发中做出更好的布局选择。

weixin_56595425的博客 3202

WPF编程基础入门 ——— 第三章 布局(七)布局面板Grid

WPF布局——布局面板GridWPF——Grid布局控件Grid简单实例——按钮排列Grid简单实例——登录界面 WPF——Grid布局控件 尽管上一篇讲解的UniformGrid能够布局统一单元格,但是很多布局中需要构建单元格大小不等,具有跨越式单元格(Span Cells) 和空白列等功能。而Grid能实现上述这些功能,它是一个使用灵活、能构建复杂UI的布局控件。 Grid最简单的用法是通过设置RowDefinitions和ColumnDefinitions属性定义单元格的总数。其中,RowDefini

m0_46334316的博客 8721

别再乱用Grid了!WPF六大布局容器适用场景保姆级指南(含布局选择决策树)

本文深入解析WPF六大布局容器(Canvas、DockPanel、StackPanel、WrapPanel、UniformGrid、Grid)的核心特性与适用场景,并提供清晰的布局选择决策树。针对常见的UI设计需求,如动态仪表盘、结构化表单、流式布局等,给出了具体的容器选择建议和实战代码示例,帮助开发者避免滥用Grid,提升界面性能和可维护性。

berry的博客 511

WPF布局控件之Grid

WPF布局控件之Grid

就这样吧 2170

C#WPF常用的9种布局方式详解

本文介绍WPF中常用的九种布局,Grid、StackPanel、WrapPanel、DockPanel、UniformGrid、Canvas、ScrollViewer、ViewBox、Border。

qq_30725967的博客 1万+

WPF基础控件布局实践指南

WPF(Windows Presentation Foundation)是微软推出的一个用于构建Windows客户端应用程序的用户界面框架。布局是WPF中的核心概念之一,它决定了控件在界面中的位置、大小以及它们之间的相互关系。良好的布局设计对于提供良好的用户体验至关重要,它不仅影响应用程序的视觉效果,还对性能有直接的影响。在WPF中,Grid控件是通过定义和来创建一个由行和列组成的表格布局。每一行或每一列的大小可以指定为固定值、自动值或者以比例分配剩余空间。

weixin_42097508的博客 733

wpf UniformGrid控件详解与示例应用

UniformGrid是WPF中一个简单实用的布局控件,特别适合需要等宽等高元素排列的场景。使用简单,无需复杂行列定义自动均匀分布子元素适合工具面板、图片网格、棋盘类游戏等布局。

一个编程的同学 1354

小龙虾 OpenClaw 安装全攻略:本地部署 AI 智能体一步到位

OpenClaw(昵称小龙虾)是一款 MIT 开源协议的本地优先 AI 智能体执行网关,支持多平台接入、本地部署,能实现自然语言驱动的设备自动化操作,区别于纯对话 AI,可直接操控系统执行实际任务,数据全程本地存储更安全。本文带来 2026 最新版 OpenClaw 安装教程,适配 Windows/macOS/Linux 全系统,新手也能一键搞定。

lujiawei00的专栏 1973

WPF常用的9种布局方式,建议收藏!

概述:本文简要介绍了WPF中布局常用控件及布局相关的属性。 文章目录一、Grid二、StackPanel三、WrapPanel四、DockPanel五、 UniformGrid六、Canvas七、总结 一、Grid Grid为WPF中最常用的布局容器, 作为View中的主要组成部分, 负责框架中整体的页面布局。 标签 含义 ShowGridLines 可以设置行业的边距线的显示 Grid. RowDefinitions 可以创建任意行, 进行固定高度与百分比高度设置 Grid. C

路虽远,行则必至! 2万+

Calpuff模型实战:从气象数据预处理到污染物扩散模拟全流程指南

本文提供了一份详尽的Calpuff模型实战指南,涵盖从气象数据预处理、地形处理到污染物扩散模拟与结果可视化的全流程。重点解析了Calmet气象场构建、Calpuff核心参数配置,并与AERMOD模型进行对比,帮助环境工程师与科研人员掌握这一强大的三维非稳态拉格朗日扩散模型,以应对复杂地形、海岸熏烟等实际模拟挑战。

s4t5u6v7的博客 458

手把手教你用单结晶体管搭建简易振荡电路(含电路图和波形分析)

本文详细介绍了如何使用单结晶体管(UJT)搭建简易振荡电路,包括电路设计、波形分析和实战技巧。通过具体的电路图和参数计算,帮助电子爱好者和工程师快速掌握UJT振荡器的设计与调试方法,适用于脉冲信号生成和时钟源制作等应用场景。

weixin_29207533的博客 516

WPF and Silverlight 学习笔记(八):WPF布局管理之Grid、UniformGrid

一、Grid Grid是以表格形式组织控件的一种布局方式,与Java AWT中的GridLayout类似,但区别在于 WPF中的Grid的每一个单元格中可以放置多个控件,但控件可能会层叠在一起 WPF中的Grid支持单元格的合并,类似于HTML中的table td中的rowspan和colspan Grid中的行和列可以自定义高度(Height)和宽度(Width)...

XCH1992的博客 245

编译hive-3.1.3(3.0.0)和编译tez-0.10.2适配hadoop-3.3.4以及hadoop-3.2.2(附安装包)

编译hive-3.1.3(3.0.0)和编译tez-0.10.2适配hadoop-3.3.4以及hadoop-3.2.2(附安装包)

2301_77356579的博客 2596

WPF 入门笔记 - 01 - 入门基础以及常用布局

不管是WinForm应用程序还是WPF应用程序,实际上都是一个进程,一个进程可以包含多个线程,其中有一个是主线程,其余的是子线程。具体如下图,要实现控件 0 的布局, 那么先要实现 0 的子控件 01,02... 的布局, 要实现 01 的布局, 那么得实现 01 的子控件 001,002... 的布局, 如此循环直到子控件的布局完成后, 再完成父控件的布局, 最后递归回去直到递归结束, 这样整个布局过程就完成了。是最基本的面板,只是一个存储控件的容器,它不会自动调整内部元素的排列及大小。

Gefangenes的博客 4768

当AI学会写“自传”:OpenClaw 的 SOUL.md 如何把配置文件变成一颗会变形的心

SOUL.md。

步子哥的博客 1309

语言模型推理能力与计算表达力深度解析

语言模型的推理能力本质上是一种知识迁移与泛化应用的过程,其核心在于Transformer架构中的自注意力机制和前馈网络的协同作用。计算表达力作为衡量模型能力的关键指标,涉及函数逼近、组合泛化和上下文理解等多个维度。随着模型规模的扩大,涌现能力现象揭示了参数规模与推理能力之间的非线性关系。在实际应用中,通过提示工程和微调策略可以有效激活和优化模型的推理表现。当前研究正探索模块化架构和世界模型整合等方向,以突破长程推理和因果关系建模等前沿挑战。本文深入探讨了语言模型推理泛化的技术原理与实践方法,为理解计算表达力

weixin_42521032的博客 341

WPF布局控件深度解析:UniformGrid与StackPanel实战指南

在WPF桌面应用开发中,布局容器是构建用户界面的基础。UniformGrid通过行列均分机制实现子元素的等尺寸排列,StackPanel则基于线性堆叠逻辑完成元素的顺序布局。理解两者的测量与排列原理,能有效提升界面自适应能力与渲染性能。在仪表盘、功能入口面板、侧边栏导航等场景中,合理选用UniformGrid或StackPanel可显著减少手写行列定义的重复劳动。本文深入拆解UniformGrid的均分机制与StackPanel的堆叠特性,结合实战案例与性能对比,帮助开发者避开常见布局陷阱,做出更优的选型决

weixin_28710999的博客 232

华为OD机试新系统真题【迷宫相遇】

华为OD机试 新系统真题【迷宫相遇】,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解,以及在线OJ模拟做题。华为OD机试真题【迷宫相遇】多语言题解。

qq_45776114的博客 765

WPF布局控件全解析:从Grid到Canvas的实战指南

在桌面应用开发中,UI布局是决定界面质量与可维护性的核心骨架。理解布局容器的工作机制,不仅能解决窗口拉伸时的界面错乱问题,还能显著提升多分辨率适配能力。WPF提供了一套强大的声明式布局系统,其中Grid、StackPanel、DockPanel、WrapPanel、Canvas等布局控件各司其职,配合Measure/Arrange两阶段测量排列机制,让开发者无需手动计算像素即可构建自适应界面。掌握这些布局控件的特点与适用场景,是高效开发WPF应用的关键技能。从基础概念到工程实践,合理选型布局容器、控制嵌套层

weixin_34098209的博客 176

TI硬件笔试面试题型解析上

摘要: 本专栏聚焦大厂硬件笔试面试题解析,当前第14期以德州仪器(TI)为例,涵盖模拟电路与数字电路核心考点。模拟电路部分涉及最大功率传递定理、运放设计(虚短/虚断)、共模抑制比(CMRR)及高频PCB信号完整性;数字电路包括CMOS与TTL对比、建立/保持时间、竞争冒险消除、D触发器分频及“线与”逻辑实现。文章强调通过例题掌握解题方法与知识点,助力读者应对硬件工程岗位的笔试与面试挑战,附常见考点总结与实用建议。全文注重理论与实践结合,提供典型题型解析与设计思路。(150字)

启芯硬件的博客 950

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

一文读懂WPF布局

注意:UniformGrid 没有内置的 Spacing 属性,需通过子元素的 Margin 或容器的 Padding 实现间距3。

Marzlam的博客 2280

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

WPF基本布局容器与控件

快速入门WPF的布局和控件

啊丢_的博客 1471

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

WPF 布局控件完全指南:Grid、StackPanel、WrapPanel、DockPanel、Canvas、Border 一篇搞懂

用 Panel 打破“一个容器只能放一个控件”的限制,再根据排列方式选对面板。日常开发中,Grid + DockPanel 能覆盖绝大多数窗口布局,WrapPanel、StackPanel 负责局部流式排列,Canvas 留给绘图与设计器,Border 负责颜值。掌握了这 8 个控件,WPF 的界面布局基本就难不倒你了。

2501_94699871的博客 288

WPF 布局基础概述

深入了解 WPF 布局基础,并要求详细讲解、代码示例、测试代码、适用场景及使用方法。结合之前的上下文(MVVM 模式、Prism 框架、动态模块加载、模块热加载、模块卸载等),我将提供一个全面的指南,涵盖 WPF 所有主要布局控件的详细讲解,包含代码示例、测试代码、适用场景和使用方法,确保与 Prism 框架和实时消息查看器示例无缝衔接。以下内容将结构化、简洁且详尽,适用于从初学者到高级开发者的需求。WPF(Windows Presentation Foundation)的布局系统基于 布局容器(Panel

专注于前沿技术的探索与实践,热衷于从代码逻辑、架构设计到行业应用等多维度深挖技术本质。期待在技术之路上与你共同成长~ 1221

WPF布局

大家都知道,UI是做好一个软件很重要的因素,如果没有一个漂亮的UI,功能做的再好也无法吸引很多用户使用,而且没有漂亮的界面,那么普通用户会感觉这个软件没有多少使用价值 WPF作为专业的界面技术,布局功能是它的核心技术之一。友好的用户界面和良好的用户体验离不开设计精良的布局。日常工作中,WPF设计师最大的工作量就是布局和动画,WPF的布局控件都在System.Windows.Controls.Pan...

weixin_44588733的博客 529
上一篇: 深入浅出 C# 扩展方法:为现有类型 “无痛” 扩展功能
下一篇: 深入理解 C# 特性(Attribute):概念、实现与实战
bugcome_com
博客等级 码龄3年 32粉丝 131原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bugcome_com

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值