WPF XAML+布局+控件

WPF XAML+布局+控件

一、WPF 与 XAML 简介

WPF(Windows Presentation Foundation)是微软推出的基于 .NET Framework(以及 .NET Core/5+)的现代 UI 框架,采用矢量渲染、数据绑定、样式模板等先进技术,能够构建富客户端桌面应用。

XAML(eXtensible Application Markup Language)是一种声明式 XML 语言,用于定义 WPF 的用户界面。它将界面设计与业务逻辑分离,使开发人员可以专注于 C#/VB 代码,而设计人员可以使用 Blend 等工具直接编写 XAML。

二、XAML 详解

2.1 XAML 命名空间

在XAML(可扩展应用程序标记语言)中, 命名空间是类似于C#中 using 的关键机制。 它通过 xmlns 属性将XAML中的元素标签(如 <Button>)映射到实际的.NET类库,使XAML解析器能准确定位和实例化所需的C#类型

XAML命名空间声明通常位于XAML文件的根元素中, 语法是 xmlns[:可选前缀]="命名空间标识符"。 每个 WPF XAML 文件根元素包含以下常见命名空间:

xml 复制代码
<Window x:Class="WpfApp.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"
        Title="MainWindow" Height="450" Width="800">
    <!-- 界面内容 -->
</Window>

xmlns 默认命名空间: WPF 核心元素(控件、布局等)。
xmlns:x : XAML 专用指令,如 x:Class, x:Name, x:Static 等。
xmlns:d 和 mc:Ignorable:用于设计时支持。

XAML 语言特性命名空间 (xmlns:x):通过前缀 x: 来引用,它包含了XAML语言本身定义、与UI框架无关的一些指令和功能,例如 x:Name、x:Key、x:Class 等。详细功能见下表:

指令 描述
x:Class 指定XAML文件编译后生成的partial类的命名空间和类名,即代码隐藏文件的类名。
x:Name 为XAML元素设置一个唯一标识符,可以在代码隐藏文件中直接访问该对象。
x:Key 为资源字典中的每个资源定义一个唯一的键,通常用于 StaticResource 或 DynamicResource 标记扩展进行检索。
x:TypeArguments 为泛型类指定泛型参数的类型。

2.2 XAML 语法基础

对象元素: 使用尖括号声明,如 <Button>
特性(Attribute): 设置属性或事件,如 Content="Click"。
嵌套内容: 支持子元素,例如 Grid 中放置多个控件。
XAML 中的值转换: 内置类型转换器将字符串转换为对应类型(如 Background="Red" -> SolidColorBrush)。

xml 复制代码
<!-- 带内容的 Grid 容器 -->
<Grid>
    <!-- 创建一个 Button 对象 -->
    <Button  Background="Red" Height="50" Width="100" Content="按钮"/>
    <TextBlock Text="Hello WPF" />
</Grid>
<!--解析器会将 <Button> 转换成 new Button(),将 <Grid> 转换成 new Grid()。-->

2.3 属性元素与特性语法

特性语法 适用于简单值(字符串、数字、枚举等),直接在元素标签内设置。

xml 复制代码
<Button Content="按钮" Background="Blue" Height="50" Width="100"/>

属性元素语法 是 XAML 中为复杂属性赋值的一种写法。

当属性的值无法用简单的字符串(如 "Red")表示,而需要嵌套对象、集合或更多子属性时,就用 <类型.属性名> 的形式,把属性写成独立的子元素。
实现一个渐变色按钮

xml 复制代码
	<Window x:Class="WPF_XMAL_Basics_Demo01.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:WPF_XMAL_Basics_Demo01"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <!-- 带内容的 Grid 容器 -->
    <Grid>
        <!-- 创建一个 Button 对象 -->
        <Button Height="50" Width="100" Content="按钮">
            <Button.Background>
                <LinearGradientBrush>
                		<!-- Offset种0是起点 1是终点 -->
                    <GradientStop Color="Red" Offset="0"/>
                    <GradientStop Color="Yellow" Offset="0.5"/>
                    <GradientStop Color="Green" Offset="1"/>
                </LinearGradientBrush>
            </Button.Background>
        </Button>
    </Grid>
</Window>

2.4 附加属性

附加属性允许父元素为子元素设置属性(例如 Grid.Row、Grid.Column)。语法为 <父元素.附加属性名>。

xml 复制代码
<Grid>
    <!--将Grid分为三行-->
    <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition/>
        <RowDefinition/>
    </Grid.RowDefinitions>
    <!--
    		 在Grid的第一行放一个红色的按钮,在第二行放一个蓝色的按钮,在第三行放一个黄色的按钮
			 这个时候Grid.Row 为附加属性 而Grid.Row在 Button标签中并没有这个属性,这个属性来自于父元素Grid
		-->
    <Button Grid.Row="0" Background="Red" Content="第一行"/>
    <Button Grid.Row="1" Background="Blue" Content="第二行"/>
    <Button Grid.Row="2" Background="Yellow" Content="第三行"/>
</Grid>

2.5 标记扩展

(后续会写一篇详解,关于标记拓展和数据绑定以及MVVM,这里只介绍基础概念和如何标记拓展)

标记扩展允许在运行时解析属性值,使用花括号 {} 包裹;
常用标记扩展:

扩展 示例 作用
{Binding} Text="{Binding UserName}" 数据绑定
{StaticResource} Background="{StaticResource myBrush}" 引用静态资源
{x:Null} Tag="{x:Null}" 设置为 null
{x:Static} Text="{x:Static local:Constants.AppName}" 引用静态成员
{x:Type} DataType="{x:Type Button}" 获取 Type 对象

标记扩展也可以嵌套: Text="{Binding Path={x:Static local:Paths.DefaultPath}}"。

xml 复制代码
<!--绑定UserName-->
<TextBlock Text="{Binding UserName}" />
<Button Background="{StaticResource ErrorBrush}" />

2.6 代码隐藏文件

代码隐藏文件就是和 XAML 界面"配对"的那个 C# 文件,代码隐藏文件是写"逻辑"的地方,让 XAML 画出来的界面真正"活"起来。XAML 与后台代码通过 x:Class 关联。在 .xaml.cs 中使用 InitializeComponent() 加载 XAML。

InitializeComponent()是 XAML 框架提供的方法,负责将 XAML 设计图实例化为真实的控件树,并建立后台代码与界面元素的连接。它是 UI 能够显示和交互的基石。

cs 复制代码
public partial class MainWindow : Window{
    public MainWindow(){
        InitializeComponent();
    }
}

三、WPF 布局系统

WPF 的布局系统是 UI 框架的核心,它负责自动计算每个控件的大小和位置,以适应窗口大小变化、内容更新或字体缩放等动态场景。
核心思想就是容器说了算: 在 WPF 中,控件通常不自己决定位置,而是由它的父容器(如 Grid、StackPanel)来安排。每个容器有自己的布局规则(堆叠、网格、停靠等),递归地管理内部所有子元素。

3.1 布局原则

WPF 布局系统背后有几个核心的设计原则
1. 尺寸由容器决定,而非自身: 不写死 Width/Height,让父容器根据内容和规则自动分配大小。
2. 位置由容器决定,而非坐标: 避免 Canvas 绝对定位,用 Grid、StackPanel 等容器自动安排位置。
3. 使用比例和自动尺寸,而非像素: 用 * 和 Auto 按比例或内容分配空间,不依赖固定像素值。
4. 对齐与边距控制间距,而非空白元素: 用 HorizontalAlignment、Margin 等属性控制间距,不要用空元素占位。
5. 容器可以嵌套,但不要过深: 嵌套布局可行,但过深会影响性能,优先用 Grid 跨行跨列简化结构。
6. 让布局自动适应内容变化: 确保父容器能随内容动态增减而自动调整大小,必要时包裹 ScrollViewer。
7 .设计时考虑 DPI 缩放和字体: 使用与设备无关的坐标(WPF 单位),避免依赖绝对像素值,保证高 DPI 下正常显示。

只需要记住让容器决定尺寸和位置,使用比例/自动尺寸,通过对齐/边距控制间距,避免固定值和绝对坐标。

3.2 核心布局容器

这里主要介绍Grid和StackPanel两种,这两种容器基本上能解决90%及以上的问题
Grid(网格)

最强大和常用的布局容器,类似于 HTML 的 <table>。可以定义行和列,将控件放入指定单元格。
常用属性: Grid.Row, Grid.Column, Grid.RowSpan, Grid.ColumnSpan。

xml 复制代码
<!--ShowGridLines属性用于显示网格线-->
<!--ShowGridLines属性用于显示网格线-->
<Grid ShowGridLines="True">
    <!--Grid.RowDefinitions用于定义行-->
    <Grid.RowDefinitions>
        <!--RowDefinition用于定义行的高度-->
        <RowDefinition Height="Auto"/>
        <!-- 自适应内容高度 -->
        <RowDefinition Height="*"/>
        <!-- 按比例分配剩余空间 -->
        <RowDefinition Height="50"/>
        <!-- 固定高度 -->
    </Grid.RowDefinitions>
    <!--Grid.ColumnDefinitions用于定义列-->
    <Grid.ColumnDefinitions>
        <!--ColumnDefinition用于定义列的宽度-->
        <ColumnDefinition Width="2*"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    <!--Grid.Row表示行索引,Grid.Column表示列索引 从下标0开始-->
    <!--Grid.RowSpan表示行跨度,Grid.ColumnSpan表示列合并-->
    <TextBlock Text="Header" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="1"/>
    <Button Grid.Row="1" Grid.Column="0" Content="Left"/>
    <Button Grid.Row="1" Grid.Column="1" Content="Right"/>
    <Button Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" Content="Footer"/>
</Grid>

StackPanel(堆叠面板)

沿水平或垂直方向顺序排列子元素,不换行。

Orientation 可选 Vertical(默认)或 Horizontal。

xml 复制代码
<!--Orientation的作用是决定StackPanel中子元素的排列方向-->
<!--Orientation="Vertical"表示子元素垂直排列,Orientation="Horizontal"表示子元素水平排列-->
<StackPanel Orientation="Vertical">
    <Button Content="Top"/>
    <Button Content="Middle"/>
    <Button Content="Bottom"/>
</StackPanel>

主要使用五种核心容器 Grid和StackPannel最常见

容器 适用场景
Grid 表单布局、仪表盘、整体页面框架,需要行列对齐和比例分配空间时。
StackPanel 工具栏、菜单、垂直或水平排列的简单列表,不需要换行或复杂对齐。
DockPanel 类似 Visual Studio 的窗口布局(顶部菜单+底部状态栏+左右停靠+中央内容区)。
WrapPanel 标签云、图片墙、动态添加的按钮组,空间不足时自动换行/换列。
Canvas 绘图程序、图形编辑器、需要绝对坐标定位的动画或自定义绘制元素。

3.3 布局通用属性

所有派生自 FrameworkElement 的控件都拥有以下重要布局属性:

属性 描述
Width / Height 固定宽高
MinWidth / MaxWidth, MinHeight / MaxHeight 尺寸范围限制
Margin 元素外部的空白(顺序:左,上,右,下)
Padding 元素内容与边界间的空白(只有部分控件支持,如 Button)
HorizontalAlignment 水平对齐:Left, Center, Right, Stretch
VerticalAlignment 垂直对齐:Top, Center, Bottom, Stretch
Visibility Visible, Hidden, Collapsed(Collapsed 不占空间)

当同时设置 Width 和 HorizontalAlignment="Stretch" 时,Width 优先级更高。

四、WPF 控件详解

4.1 按钮类 (Button, RepeatButton)

WPF 按钮类控件都派生自 ButtonBase,核心能力是 单击(Click) 和 命令(Command)。

Button : 用户单击触发 Click 事件,可包含任意内容(图像、文本、布局)。

xml 复制代码
<Button Click="OnSaveClick">
    <StackPanel Orientation="Horizontal">
        <Image Source="save.png" Width="16"/>
        <TextBlock Text="Save"/>
    </StackPanel>
</Button>

RepeatButton : 按住时重复触发 Click 事件(用于调节数值或滚动)。

xml 复制代码
<RepeatButton Content="+" Delay="500" Interval="100" Click="Increase_Click"/>

其他按钮

控件 特点
Button 标准按钮,按下弹起触发一次。
RepeatButton 长按时周期性重复触发。
ToggleButton 开关状态:按下/弹起(IsChecked)。
CheckBox 勾选框,可三态(IsThreeState)。
RadioButton 单选框,同组内只能选一个。

4.2 文本输入与显示 (TextBox, TextBlock, Label, PasswordBox)

TextBox 最通用的文本输入控件,支持单行/多行、撤销、复制/粘贴。常用于普通表单输入、备注框、可编辑字段
关联属性

属性 说明
Text 当前文本内容(用于绑定)。
TextWrapping 是否换行(多行输入常用 Wrap)。
AcceptsReturn 是否允许输入回车换行(多行必须设为 true)。
AcceptsTab 是否允许 Tab 键输入(通常保留用于焦点导航)。
MaxLength 最大字符数。
SpellCheck.IsEnabled 启用拼写检查(需设置 xml:lang)。
IsReadOnly 只读模式(视觉上可区分)。

TextBlock 量级只读文本控件,性能最好,支持内联元素(Run、LineBreak、InlineUIContainer)。常用于标签、说明文字、动态消息、需要部分高亮的文本。
关键属性

属性 说明
Text 纯文本内容(最常用)。
TextWrapping 换行方式(NoWrap / Wrap / WrapWithOverflow)。
TextTrimming 溢出裁切(None / CharacterEllipsis / WordEllipsis)。
TextDecorations 下划线、删除线等。
Inlines 内联元素集合(比纯文本更灵活)。

Label 支持访问键(Access Key)的文本控件,通常作为其他控件的标题。常用于表单字段标签(如"姓名:"),需快捷键定位到输入框。
关键属性

属性 说明
Target 指定按下 Alt+快捷键时焦点转移到的目标控件。
Content(继承自ContentControl) 可以是文本或任意UI元素。

访问键语法: 在文本中用下划线 _ 定义快捷键(例如 _Name 显示为 "Name",按 Alt+N 定位到 Target)。

xml 复制代码
<Label Target="{Binding ElementName=txtName}">_姓名:</Label>
<TextBox x:Name="txtName"/>

PasswordBox 密码输入控件,输入的字符被掩码(·或*),且不会在内存中保留明文。
关键属性

属性 说明
Password 当前密码明文(不推荐绑定,违反安全设计)。
SecurePassword 返回 SecureString(更安全)。
PasswordChar 掩码字符(默认 ●)。
MaxLength 最大长度。

获取密码的安全方式: 使用 PasswordBox.Password 仅在需要时读取,避免缓存。

文本选择

控件 需求
TextBlock 态文本(纯展示)
Label 表单标签(带快捷键)
TextBox 单行/多行普通文本输入
PasswordBox 密码输入
RichTextBox带格式的文本编辑 (字号、颜色等)
FlowDocumentScrollViewer RichTextBox(只读) 大量只读格式化文本(内置滚动)

4.3 选择控件 (CheckBox, RadioButton, ToggleButton)

WPF 的选择控件是让用户从一组选项中做出选择的控件,主要分为三类:布尔选择(是否)、单项选择(互斥)、多项选择(可多选)。

控件 行为
CheckBox 三态(选中、取消、不确定),用于布尔选项
RadioButton 互斥选择,相同 GroupName 为一组
ToggleButton 具有选中/未选中两种状态的按钮,常用于工具条

公共属性(继承自 ToggleButton)

属性 说明
IsChecked bool? 类型(true/false/null,仅 CheckBox 支持 null 表示不确定状态)。
IsThreeState 仅 CheckBox 有效,启用第三态(IsChecked = null)。
xml 复制代码
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="1*"/>
        <RowDefinition Height="1*"/>
        <RowDefinition Height="1*"/>
        <RowDefinition Height="1*"/>
    </Grid.RowDefinitions>
    <ToggleButton Grid.Row="0" Content="开关"></ToggleButton>
    <CheckBox Grid.Row="1" Content="记住我" IsChecked="True" Checked="CheckBox_Checked"/>
    <RadioButton Grid.Row="2" Content="男" GroupName="Gender" IsChecked="True"/>
    <RadioButton Grid.Row="3" Content="女" GroupName="Gender"/>
</Grid>

选择: 需要勾选框用 CheckBox,需要单选用 RadioButton,只需要按下/弹起外观的按钮用 ToggleButton

4.4 列表控件 (ListBox, ComboBox, ListView)

WPF 的列表控件用于展示集合数据,并支持选择、编辑、分组、排序等交互。核心基类是 ItemsControl,它定义了数据绑定和项模板化的基础。
公共基类 ItemsControl 的核心属性

属性 作用
ItemsSource 绑定数据集合(实现 IEnumerable,推荐 ObservableCollection)。
Items 直接添加静态项(XAML 中写 )。
DisplayMemberPath 指定显示数据对象的哪个属性(简单场景)。
ItemTemplate 数据模板,自定义每个项的呈现方式(比 DisplayMemberPath 更强大)。
ItemContainerStyle 为每个项容器(如 ListBoxItem)设置样式。
SelectedItem / SelectedIndex 当前选中项(单项)。
ItemsPanel 指定布局面板(默认 StackPanel,可换成 WrapPanel 等)。

ListBox 选择模式:SelectionMode = Single(默认)/ Extended(Ctrl/Shift 多选)/ Multiple(简单多选)。
SelectedItems 属性(只读,通常用代码或绑定自定义) 默认开启虚拟化(VirtualizingStackPanel),大数据量友好。

xml 复制代码
<ListBox ItemsSource="{Binding Users}" 
         SelectedItem="{Binding SelectedUser}"
         DisplayMemberPath="Name"/>

ComboBox IsEditable 让用户可输入文本(需配合 IsTextSearchEnabled 搜索)。
常用属性: DropDownHeight,MaxDropDownHeight。
事件: SelectionChanged,DropDownOpened / Closed。

xml 复制代码
<ComboBox ItemsSource="{Binding Cities}" 
          SelectedItem="{Binding SelectedCity}"
          IsEditable="True"/>

ListView 默认视图:GridView 可显示多列 支持自定义视图(如图标模式),通过设置 View 为自定义 ViewBase。

xml 复制代码
<ListView ItemsSource="{Binding Files}">
    <ListView.View>
        <GridView>
            <GridViewColumn Header="名称" DisplayMemberBinding="{Binding Name}"/>
            <GridViewColumn Header="大小" DisplayMemberBinding="{Binding Size}"/>
        </GridView>
    </ListView.View>
</ListView>

列表选择

控件 需求
ListBox 普通列表,支持单选/多选
ComboBox 空间有限的单选下拉
ListView + GridView 或 DataGrid 多列表格数据
DataGrid 复杂表格(编辑、排序、筛选)
TreeView 层次数据(目录、组织)
ItemsControl(自定义模板) 只展示数据(无选择)

4.5 数据表格 (DataGrid)

DataGrid 是 WPF 中最强大的表格控件,专门用于展示和编辑结构化数据。它内置了排序、筛选、编辑、分组、行细节等丰富功能,非常适合处理类似数据库或 Excel 的二维数据。

需要编辑、增删、复杂交互的表格选 DataGrid;只读多列选 ListView。

核心能力

列类型:文本列、复选框列、下拉列、超链接列、自定义模板列

交互:排序、调整列宽/顺序、编辑(单元格/行)、增删行

视觉:交替行背景、行细节展开、冻结列、网格线控制

选择:单选/多选(单元/整行)

验证:内置错误提示(红色边框/感叹号)

常用属性

属性 作用
AutoGenerateColumns 自动生成列(默认true)
CanUserAddRows 底部显示新行占位符
CanUserSortColumns 启用列排序
IsReadOnly 整体只读
SelectionMode / SelectionUnit 选择模式(单/多选,单元/整行)
FrozenColumnCount 冻结左侧列数
RowDetailsTemplate 定义行展开区域
xml 复制代码
<Window x:Class="WPF_Control_Demo03.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WPF_Control_Demo03"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
    			<!--这里AutoGenerateColumns="True"可以不写,因为默认为True,这里写上能看的更直观一点-->
        <DataGrid x:Name="MyGrid" AutoGenerateColumns="True" />
    </Grid>
</Window>

后台代码

cs 复制代码
using System.Windows;

namespace WPF_Control_Demo03{
    public partial class MainWindow : Window{
        public MainWindow(){
            InitializeComponent();
            // 造一个简单的数据集合(匿名类型)
            var data = new[]{
                new { 姓名 = "张三", 年龄 = 20, 城市 = "北京" },
                new { 姓名 = "李四", 年龄 = 25, 城市 = "上海" },
                new { 姓名 = "王五", 年龄 = 22, 城市 = "广州" }
            };
            MyGrid.ItemsSource = data;
        }
    }
}

运行后表格自动生成三列:姓名、年龄、城市,三行数据显示出来,支持排序、列宽调整。
只需给 DataGrid.ItemsSource 赋一个集合,设置 AutoGenerateColumns="True",就能立刻显示表格。

4.6 图像控件 (Image)

显示位图(BMP、PNG、JPG、ICO、GIF 等)

xml 复制代码
<Image Source="Images/logo.png" Width="100" Stretch="Uniform"/>

常用属性

属性 作用
Source 指定图像源(BitmapImage 或图像路径/URI)。
Stretch 控制图像在控件内的缩放方式:Fill(拉伸填充)、Uniform(等比例完整显示) UniformToFill(等比例裁剪填充)、None(原始尺寸)。
StretchDirection 限制拉伸方向:UpOnly(仅放大)、DownOnly(仅缩小)、Both(任意)。
Width Height 显式设置控件尺寸(受 Stretch 影响)。
MaxWidth MaxHeight 最大尺寸限制。
Opacity 透明度(0-1)。
RenderTransform 变换(旋转、缩放等)。
Clip 裁剪几何形状。

4.7 容器控件 (GroupBox, Expander, TabControl)

容器控件是专门用于布局和容纳其他元素的控件,它们负责子元素的排列、尺寸分配和位置管理。所有容器控件都继承自 Panel 抽象类。
常用容器控件一览

容器 布局特点 适用场景
Grid 表格布局(行/列),最强大灵活 复杂表单、整体页面框架
StackPanel 水平或垂直堆叠 工具栏、菜单、简单列表
WrapPanel 流式布局,空间不足时换行/换列 标签云、图片墙
DockPanel 子元素停靠(上下左右),最后一个填充剩余 窗口布局(菜单栏+状态栏+中央区)
Canvas 绝对坐标定位(Left/Top) 绘图、图形编辑器、精确放置
UniformGrid 均分行列,所有单元格大小相同 棋盘、按钮矩阵
Border 装饰容器,可绘制边框、背景、圆角 包裹单个元素,提供视觉边界
ScrollViewer 提供滚动区域 当内容超出可视区域时
GroupBox 带标题边框的容器 分组设置区域
Expander 可折叠/展开的容器 隐藏高级选项
TabControl 选项卡容器,多页内容切换 多页面视图
Frame / NavigationWindow 页面导航容器 导航型应用(XAML 页面)

布局容器(Grid, StackPanel 等)负责排列逻辑。
装饰容器(Border, ScrollViewer)为内容添加附加功能。
内容容器(GroupBox, Expander)提供扩展的视觉和行为。

优先使用 Grid 做主布局,局部用 StackPanel 或 WrapPanel,需要滚动用 ScrollViewer,绝对定位只用 Canvas。

五、综合示例

实现用户信息表单

xaml

xml 复制代码
<Window x:Class="WPF_User_Information_Form_Test.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:local="clr-namespace:WPF_User_Information_Form_Test"
        Title="用户信息表" Height="400" Width="600">
    <Grid Margin="10">
        <!-- 用户信息表格制作 -->
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <TextBlock Text="用户信息表" FontSize="20" FontWeight="Bold" HorizontalAlignment="Center" Grid.Row="0" Grid.ColumnSpan="2" Margin="0,0,0,10"/>
        <!-- 姓名 -->
        <Label Content="姓名:" Grid.Row="1" Grid.Column="0" VerticalAlignment="Center"/>
        <TextBox Text="{Binding UserName}" Grid.Row="1" Grid.Column="1" VerticalAlignment="Center"/>
        <!--性别-->
        <Label Content="性别:" Grid.Row="2" Grid.Column="0" VerticalAlignment="Center"/>
        <StackPanel Grid.Row="2" Grid.Column="1" Orientation="Horizontal">
            <!--这里默认选择男-->
            <RadioButton GroupName="Gender" Content="男" IsChecked="True"/>
            <RadioButton GroupName="Gender" Content="女" Margin="10,0,0,0"/>
        </StackPanel>

        <!--年龄-->
        <Label Content="年龄:" Grid.Row="3" Grid.Column="0" VerticalAlignment="Center"/>
        <TextBox Text="{Binding UserAge}" Grid.Row="3" Grid.Column="1" VerticalAlignment="Center"/>

        <!--城市-->
        <Label Content="城市:" Grid.Row="4" Grid.Column="0" VerticalAlignment="Center"/>
        <ComboBox x:Name="MyCity" Grid.Row="4" Grid.Column="1" Margin="5" ItemsSource="{Binding CityList}"/>
        <!-- 兴趣爱好 -->
        <Label Grid.Row="5" Grid.Column="0" Content="兴趣:" VerticalAlignment="Center"/>
        <StackPanel Grid.Row="5" Grid.Column="1" Margin="5" Orientation="Horizontal">
            <CheckBox Content="唱" Margin="0,2"/>
            <CheckBox Content="跳" Margin="0,2"/>
            <CheckBox Content="rap" Margin="0,2"/>
            <CheckBox Content="篮球" Margin="0,2"/>
        </StackPanel>
        <!--备注-->
        <Label Content="备注:" Grid.Row="6" Grid.Column="0" VerticalAlignment="Center"/>
        <!--AcceptsReturn="True"按下回车换行-->
        <!--VerticalScrollBarVisibility="Auto"内容超出文本框高度时,自动显示垂直滚动条;内容不足时隐藏。-->
        <!--TextWrapping="Wrap"文本超出控件宽度时自动强制换行,长单词也会拆分换行;-->
        <TextBox Grid.Row="6" Grid.Column="1" Margin="5" Height="60" AcceptsReturn="True" VerticalScrollBarVisibility="Auto" TextWrapping="Wrap"/>
        <!-- 按钮 -->
        <StackPanel Grid.Row="7" Grid.Column="0" Grid.ColumnSpan="2" Orientation="Horizontal" HorizontalAlignment="Center" Margin="0,10,0,0">
            <Button Content="确定" Background="Green"  Width="80" Height="30" Margin="5" VerticalAlignment="Top" Click="OkButton_Click"/>
            <Button Content="取消" Background="Red" Width="80" Height="30" Margin="5" VerticalAlignment="Top" Click="CancelButton_Click"/>
        </StackPanel>
    </Grid>
</Window>

后台代码

cs 复制代码
using System.Windows;

namespace WPF_User_Information_Form_Test{
    public partial class MainWindow : Window{
        public MainWindow(){
            InitializeComponent();
            var data = new[]{"北京" ,"上海" ,"广州" };
            MyCity.ItemsSource = data;
        }
        private void OkButton_Click(object sender, RoutedEventArgs e){
            // 收集数据并处理
            MessageBox.Show("信息已保存");
            this.DialogResult = true;
        }
        private void CancelButton_Click(object sender, RoutedEventArgs e){
            MessageBox.Show("信息未保存");
            this.DialogResult = true;
        }
    }
}

运行结果

相关推荐
Rust研习社4 小时前
Rust + PostgreSQL 极简技术栈应用开发
开发语言·数据库·后端·http·postgresql·rust
雾岛听风6914 小时前
JavaScript基础语法速查手册
开发语言·前端·javascript
c++之路4 小时前
C++ STL
java·开发语言·c++
唐青枫5 小时前
别再层层传参了!C#.NET AsyncLocal 异步上下文透传实战
c#·.net
geovindu5 小时前
go:Template Method Pattern
开发语言·后端·设计模式·golang·模板方法模式
卷Java5 小时前
上下文压缩
开发语言·windows·python
日取其半万世不竭5 小时前
Minecraft Java版社区服搭建教程(Windows版)
java·开发语言·windows
wjs20245 小时前
HTML 文本格式化
开发语言
白夜11175 小时前
C++任务调度与状态机
开发语言·c++·笔记