云计算百科
云计算领域专业知识百科平台

WPF 入门这篇就够!XAML 与五大布局面板(Grid/StackPanel/WrapPanel/DockPanel)讲明白

WPF 入门一篇就够!XAML 与五大布局面板(Grid/StackPanel/WrapPanel/DockPanel)讲明白

导语:如果把做界面比作装修,WinForms 像"拖家具摆位置",每个控件坐标写死;WPF 则像先画好户型图纸(XAML),再让家具按规则自动排列,窗口拉大缩小都不乱。本文基于我自己的 WPF 学习程序,从 XAML 是什么讲起,重点把 Grid、StackPanel、WrapPanel、DockPanel、Border 这五个最常用的布局面板讲明白,最后补上画刷、间距和样式,适合第一次接触 WPF 的同学。

一、WPF 是什么,和 WinForms 有什么区别

WPF(Windows Presentation Foundation)是微软推出的桌面 UI 框架,和 WinForms 最大的不同有两点:

  • 界面用 XAML 描述:XAML 是一种 XML 格式的标记语言,界面长什么样、控件怎么排,都写在 XAML 里;后台 .xaml.cs 只负责逻辑。界面和代码分开,结构清晰。
  • 布局靠"容器规则"而不是绝对坐标:控件放进面板里,由面板决定怎么排,窗口缩放时自动适应。
  • 简单说:WinForms 是"画"出来的,WPF 是"写"出来的。

    二、项目结构与 XAML 基础

    新建一个 WPF 项目,核心文件就这几个:

    文件作用
    App.xaml 应用程序入口,整个项目只能有一个,StartupUri 指定启动哪个窗口
    MainWindow.xaml 主窗口的界面描述
    MainWindow.xaml.cs 主窗口的后台逻辑

    App.xaml 里的 StartupUri 相当于 WinForms 里的启动窗体:

    <Application x:Class="MyApp.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    StartupUri="MainWindow.xaml">

    </Application>

    XAML 里几个常见名词先认识一下:

    • xmlns:类似 C# 里的 using,引入命名空间,照抄模板即可。
    • x:Class:指明这个 XAML 对应哪个后台类。
    • Name 和 x:Name:给控件起名字,后台才能找到它。两者大多数情况下等价;x:Name 是 XAML 的通用机制,适用于任何 XAML 对象,实际开发中推荐统一用 x:Name。

    <Button Name="btn1">按钮1</Button>
    <Button x:Name="btn2">按钮2</Button>

    【插图 1:WPF 项目结构与知识体系】
    在这里插入图片描述

    三、Window 窗口与画刷

    一个最简单的窗口长这样:

    <Window x:Class="MyApp.MainWindow"
    Title="MainWindow" Height="450" Width="800">

    <Grid>
    <Button Content="点我"/>
    </Grid>
    </Window>

    Title 是标题,Height、Width 是窗口大小。注意 Window 里只能放一个根元素,所以通常直接放一个面板,再往面板里塞控件。

    想给窗口加背景色或渐变,用 Background 配合画刷。纯色直接写颜色名,渐变用 LinearGradientBrush:

    <Window.Background>
    <LinearGradientBrush>
    <LinearGradientBrush.GradientStops>
    <GradientStop Offset="0" Color="Black"/>
    <GradientStop Offset="0.5" Color="DarkBlue"/>
    <GradientStop Offset="1" Color="White"/>
    </LinearGradientBrush.GradientStops>
    </LinearGradientBrush>
    </Window.Background>

    Offset 是这个颜色在 0~1 整条渐变带上的位置,颜色之间会自动平滑过渡。

    四、布局面板总览

    WPF 的面板就是"装控件的容器",不同面板有不同的排列规则:

    面板排列规则典型场景
    Grid 按行、列组成网格,控件指定放在哪个格子 最常用,表单、整体页面骨架
    StackPanel 子元素排成一条线(水平或垂直) 工具栏、纵向排列的一组按钮
    WrapPanel 排不下自动换行 标签云、卡片流
    DockPanel 子元素贴边停靠 顶部菜单、底部状态栏的经典布局
    Border 不是严格意义的面板,给内容加边框和背景 包裹一块区域

    【插图 2:五大布局面板排列规则对比】
    在这里插入图片描述

    五、Grid 网格(最常用,重点)

    Grid 可以理解成一张 Excel 表,先定义几行几列,再把控件放进对应格子。默认只有一行一列。

    <Grid>
    <!– 定义 4 行 –>
    <Grid.RowDefinitions>
    <RowDefinition Height="60"/>
    <RowDefinition Height="60"/>
    <RowDefinition Height="Auto"/>
    <RowDefinition Height="*"/>
    </Grid.RowDefinitions>

    <!– 定义 4 列 –>
    <Grid.ColumnDefinitions>
    <ColumnDefinition Width="60"/>
    <ColumnDefinition Width="*"/>
    <ColumnDefinition Width="2*"/>
    <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    </Grid>

    行高和列宽有三种写法,这是初学者必须搞懂的:

    • 固定数字:如 60,就是 60 像素,雷打不动。
    • Auto:这行/列多大,由里面的内容撑开,内容多高就多高。
    • 星号 *:按比例分剩下的空间。上面 * 和 2* 表示剩余空间按 1:2 分配,窗口拉大时它们一起变。

    控件用附加属性 Grid.Row、Grid.Column 指定位置(编号从 0 开始):

    <Button Content="按钮1" Grid.Row="0" Grid.Column="0"/>
    <Button Content="按钮2" Grid.Row="3" Grid.Column="2"/>

    单元格合并

    让一个控件跨多行或多列,用 RowSpan、ColumnSpan:

    <!– 从第 1 行开始,跨 2 行;从第 0 列开始,跨 2 列 –>
    <Button Content="单元格合并" Grid.Row="1" Grid.Column="0"
    Grid.RowSpan="2" Grid.ColumnSpan="2"/>

    六、StackPanel 堆叠面板

    StackPanel 把所有子元素排成一条直线,Orientation 控制方向:

    <!– 垂直排列,默认值 –>
    <StackPanel Orientation="Vertical">
    <Button Content="按钮1"/>
    <Button Content="按钮2"/>
    <Button Content="按钮3"/>
    </StackPanel>

    <!– 水平排列,常用来做一排工具栏 –>
    <StackPanel Orientation="Horizontal">
    <Button Content="新建"/>
    <Button Content="打开"/>
    <Button Content="保存"/>
    </StackPanel>

    特点是子元素会沿排列方向一直堆下去,不会自动换行,内容超出窗口会被裁掉。

    七、WrapPanel 自动换行面板

    WrapPanel 和 StackPanel 很像,区别是一行排不下时会自动换到下一行,窗口拉宽变窄时重新排列:

    <WrapPanel Orientation="Horizontal">
    <Button Content="标签1" Width="100" Margin="5"/>
    <Button Content="标签2" Width="100" Margin="5"/>
    <Button Content="标签3" Width="100" Margin="5"/>
    <Button Content="标签4" Width="100" Margin="5"/>
    </WrapPanel>

    适合做标签云、卡片这种数量不固定、希望自适应排列的场景。

    八、DockPanel 停靠面板

    DockPanel 让子元素像贴膏药一样贴在容器的上、下、左、右四条边上,用附加属性 DockPanel.Dock 指定:

    <DockPanel LastChildFill="False">
    <Button DockPanel.Dock="Top" Content="上"/>
    <Button DockPanel.Dock="Left" Content="左"/>
    <Button DockPanel.Dock="Right" Content="右"/>
    <Button DockPanel.Dock="Bottom" Content="下"/>
    </DockPanel>

    LastChildFill 表示最后一个元素是否自动填满剩余空间。设为 True 时,最后一个控件会占满中间区域,这正是"顶部菜单 + 底部状态栏 + 中间内容"的经典布局写法。

    九、Border 边框

    Border 用来给一块内容加边框、圆角和背景,它只能包裹一个子元素,里面通常再放一个面板:

    <Border BorderBrush="Red" BorderThickness="2" CornerRadius="6" Background="#f5f5f5">
    <StackPanel>
    <TextBox Width="120"/>
    <PasswordBox Width="120"/>
    </StackPanel>
    </Border>

    BorderThickness 是边框粗细,CornerRadius 是圆角大小。

    十、Margin 间距与对齐

    控件和周围的距离用 Margin,顺序是"左、上、右、下":

    <!– 左10 上20 右10 下30 –>
    <Button Content="间距测试" Margin="10,20,10,30"/>

    也可以用 Thickness 显式写,更直观:

    <Button Content="click me">
    <Button.Margin>
    <Thickness Left="20" Top="20" Right="10" Bottom="30"/>
    </Button.Margin>
    </Button>

    控件在格子里靠哪边,用 HorizontalAlignment、VerticalAlignment 控制(如 Left、Center、Stretch)。

    十一、Style 样式入门

    如果一堆按钮都要同样的背景色,一个个写属性很麻烦,可以定义一个样式统一管理。在窗口的 Resources 里定义,用 x:Key 起名:

    <Window.Resources>
    <Style x:Key="ButtonDefault" TargetType="Button">
    <Setter Property="Background" Value="Khaki"/>
    <Setter Property="Foreground" Value="DarkBlue"/>
    <Setter Property="Opacity" Value="0.8"/>
    </Style>
    </Window.Resources>

    • TargetType:这个样式作用于哪种控件。
    • Setter:把某个属性设成某个值,想设几个就写几个。

    控件通过 StaticResource 引用样式名:

    <Button Content="上" Style="{StaticResource ButtonDefault}"/>

    这样所有引用同一样式的按钮外观统一,以后改风格只改一处。

    【插图 3:程序实际运行界面】
    在这里插入图片描述

    十二、常见坑

  • Window 里直接放多个控件,报错。 Window、Border 这类元素只能有一个直接子元素。正确做法是先放一个面板(如 Grid),再把多个控件放进面板里。

  • Grid 里的控件不指定 Row/Column,全挤在左上角。 不写 Grid.Row、Grid.Column 时默认都是 0,多个控件会叠在同一个格子。放到哪个格子要显式写出来。

  • 分不清固定值、Auto 和星号。 固定值写死像素;Auto 由内容撑开;星号按比例分剩余空间。想让某块区域随窗口一起缩放,就用星号,而不是固定数字。

  • StackPanel 内容超出窗口被裁掉还以为控件丢了。 StackPanel 不会自动换行,排不下就溢出。需要换行的场景改用 WrapPanel。

  • 样式定义了但控件没生效。 检查控件的 Style="{StaticResource 样式名}" 是否引用,以及 x:Key 名字是否完全一致;样式定义要放在使用它的元素能访问到的 Resources 里。

  • 十三、小结

  • WPF 用 XAML 声明界面、后台写逻辑,布局靠容器规则自动适应,不依赖绝对坐标。
  • 五大面板各有分工:Grid 画网格(最常用)、StackPanel 排成一条线、WrapPanel 自动换行、DockPanel 贴边停靠、Border 加边框。
  • Grid 的行高列宽记住三种:固定值、Auto、星号比例;跨行跨列用 RowSpan、ColumnSpan。
  • 画刷管背景、Margin 管间距、Style 管统一外观,这三样配合面板就能搭出规整的界面。
  • 赞(0)
    未经允许不得转载:网硕互联帮助中心 » WPF 入门这篇就够!XAML 与五大布局面板(Grid/StackPanel/WrapPanel/DockPanel)讲明白
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!