WPF 学习总结
一、WPF 基础概念
1.1 什么是 WPF
- WPF (Windows Presentation Foundation):微软推出的基于 .NET Framework 的桌面客户端 UI 框架。
- 使用 XAML 标记语言来定义界面,实现 UI 与逻辑分离。
- 应用程序结构:
Application → Window / NavigationWindow → Page / 控件。
1.2 WPF 编译原理
.xaml 文件编译为 .baml(二进制资源文件),再嵌入到程序集生成的二进制文件中。
.xaml.cs(Code-Behind 代码隐藏文件)编译为普通的 .cs 二进制代码。
二、XAML 语法
2.1 XAML 概述
- XAML(Extensible Application Markup Language)是一种声明性标记语言,类似 HTML/XML。
.xaml 文件本质上是 XML 文件,区分大小写。
2.2 常用命名空间
| 命名空间 |
前缀 |
用途 |
http://schemas.microsoft.com/winfx/2006/xaml/presentation |
默认 |
WPF 核心控件/元素 |
http://schemas.microsoft.com/winfx/2006/xaml |
x: |
XAML 基础关键字(x:Class, x:Name, x:Key, x:Array, x:Static 等) |
http://schemas.microsoft.com/expression/blend/2008 |
d: |
设计时预览属性(仅在 VS/Blend 中生效,运行时忽略) |
http://schemas.openxmlformats.org/markup-compatibility/2006 |
mc: |
标记兼容性,配合 mc:Ignorable="d" 告知编译器忽略 d: 前缀 |
clr-namespace:项目名 |
local: |
引用当前项目的 CLR 命名空间 |
2.3 XAML 语法要点
- 标签本质 :是一个类(对象),WPF 中称为元素 或控件。
- 标签类型:双标签(非空标签,闭合标签)、单标签(空标签)。
- 属性 :只出现在开始标签中,以键值对形式存在,官方称为特性语法。
- 内容区:开始标签和结束标签之间的信息,可以包含文本或子标签。
- 附加属性 :标签本身没有的属性,由其他标签附加而来,如
Grid.Row、Grid.Column、DockPanel.Dock。
- 标记扩展 :使用
{} 语法,如 {StaticResource key}、{Binding Path}。
2.4 实体字符
| 实体字符 |
含义 |
< |
小于号 < |
> |
大于号 > |
  |
空格 |
¥ |
人民币符号 ¥ |
© |
版权符号 © |
® |
注册商标符号 ® |
三、App.xaml 与窗体启动方式
3.1 三种启动方式
方式一:StartupUri 属性(推荐)
<Application StartupUri="MainWindow.xaml">
方式二:Startup 事件(推荐)
<Application Startup="Application_Startup">
private void Application_Startup(object sender, StartupEventArgs e)
{
this.ShutdownMode = ShutdownMode.OnExplicitShutdown;
Window1 w1 = new Window1(100);
w1.ShowDialog();
this.ShutdownMode = ShutdownMode.OnMainWindowClose;
}
方式三:自定义 Main 方法(不推荐)
[STAThread]
public static void Main(string[] args)
{
Application app = new Application();
app.StartupUri = new Uri("Window1.xaml", UriKind.Relative);
app.Run();
}
- 需要在 App.xaml 中设置生成操作为无,避免多个入口函数。
- 必须加
[STAThread] 线程安全特性。
3.2 窗体显示方式
ShowDialog():模态窗口(阻塞式)
Show():非模态窗口
app.Run(win):指定主窗口运行
app.MainWindow = win; win.Show(); app.Run():先设置主窗口再运行
四、布局控件
4.1 Grid(网格布局)
- 最常用的布局容器,支持行列定义。
- 定义列 :
Grid.ColumnDefinitions + ColumnDefinition
- 定义行 :
Grid.RowDefinitions + RowDefinition
- 单元格合并 :
Grid.RowSpan、Grid.ColumnSpan
- 列宽可以使用
*(比例关系),如 2*、3*。
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<!-- 控件放置 -->
<Button Grid.Row="0" Grid.Column="0" Content="按钮"/>
</Grid>
4.2 StackPanel(堆叠面板)
- 子元素按水平或垂直方向依次排列(默认垂直)。
- 适用于简单的线性布局。
4.3 WrapPanel(自动换行面板)
4.4 DockPanel(停靠面板)
- 子元素可以停靠在上、下、左、右四个方向。
- 最后一个子元素默认填充剩余空间。
<DockPanel>
<Button DockPanel.Dock="Top" Content="上"/>
<Button DockPanel.Dock="Bottom" Content="下"/>
<Button DockPanel.Dock="Left" Content="左"/>
<Button DockPanel.Dock="Right" Content="右"/>
<StackPanel Background="Orange"/> <!-- 填充剩余空间 -->
</DockPanel>
4.5 Border(边框)
- 用于为子元素添加边框和背景。
- 常用属性:
BorderBrush、BorderThickness、CornerRadius(圆角)、Background。
五、样式(Style)
5.1 三种样式级别(优先级从高到低)
- 行内样式:直接在控件标签上设置属性
- 局部样式 :定义在
Window.Resources 中,仅当前窗体有效
- 全局样式 :定义在
Application.Resources 中,整个应用程序有效
5.2 样式语法
<Style x:Key="buttonStyle1" TargetType="Button">
<Setter Property="Background" Value="Red"/>
<Setter Property="Foreground" Value="Green"/>
<Setter Property="Width" Value="100"/>
<Setter Property="Height" Value="100"/>
</Style>
5.3 样式继承(BasedOn)
- 通过
BasedOn="{StaticResource BaseStyle}" 继承基础样式。
<Style x:Key="BaseStyle" TargetType="Control">
<Setter Property="Width" Value="120"/>
<Setter Property="Height" Value="30"/>
</Style>
<Style x:Key="TextBoxStyle1" BasedOn="{StaticResource BaseStyle}" TargetType="TextBox">
<Setter Property="Grid.Row" Value="0"/>
<Setter Property="Grid.Column" Value="1"/>
</Style>
5.4 使用样式
<Button Style="{StaticResource buttonStyle1}" Content="按钮"/>
六、资源(Resources)
6.1 资源字典(ResourceDictionary)
- 用于存储可重用的样式、模板、数据等。
- 定义在
Application.Resources 或 Window.Resources 中。
6.2 合并资源字典
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Resources/Dictionary1.xaml"/>
<ResourceDictionary Source="/Resources/Dictionary2.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
6.3 资源字典文件示例
<!-- Dictionary1.xaml -->
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key="LabelStyle" TargetType="Label">
<Setter Property="Content" Value="_Account"/>
<Setter Property="Target" Value="{Binding ElementName= txtAccount}"/>
</Style>
</ResourceDictionary>
6.4 快捷键设置(Label 的 Target 属性)
_Account 中的下划线表示快捷键为 Alt + A。
Target="{Binding ElementName= txtAccount}" 将焦点定位到对应的输入控件。
七、常用控件
7.1 内容控件
| 控件 |
说明 |
示例 |
Button |
按钮 |
<Button Content="点击" Click="Button_Click"/> |
Label |
标签(支持快捷键) |
<Label Content="_Account"/> |
TextBlock |
文本块(轻量级) |
<TextBlock>文本内容</TextBlock> |
7.2 输入控件
| 控件 |
说明 |
TextBox |
文本框 |
PasswordBox |
密码框 |
ListBox |
列表选择框 |
7.3 列表控件
| 控件 |
说明 |
ListBox |
列表控件,支持 ItemsSource 绑定数据源 |
ComboBox |
下拉选择框 |
7.4 选项卡控件
<TabControl>
<TabItem Header="军事">
<StackPanel>
<TextBlock>军事界面</TextBlock>
</StackPanel>
</TabItem>
<TabItem Header="娱乐">
<TextBlock>娱乐界面</TextBlock>
</TabItem>
</TabControl>
7.5 控件对齐方式
VerticalAlignment:垂直对齐(Top、Bottom、Center、Stretch)
HorizontalAlignment:水平对齐(Left、Right、Center、Stretch)
VerticalContentAlignment:内容垂直对齐
HorizontalContentAlignment:内容水平对齐
Margin:外边距(顺序:左、上、右、下)
八、数据绑定
8.1 静态资源绑定
<Window.Resources>
<sys:String x:Key="str1">成龙</sys:String>
<x:Array x:Key="items" Type="sys:String">
<sys:String>蔡徐坤</sys:String>
<sys:String>小刚</sys:String>
</x:Array>
</Window.Resources>
<TextBlock Text="{StaticResource str1}"/>
<ListBox ItemsSource="{StaticResource items}"/>
8.2 DataContext 绑定(数据上下文)
- 通过
DataContext 设置数据源,使用 {Binding Property} 绑定属性。
<!-- 引入命名空间 -->
xmlns:vm="clr-namespace:项目名.Model"
<Window.DataContext>
<vm:DataViewModel/>
</Window.DataContext>
<TextBlock Text="{Binding Id}"/>
<TextBlock Text="{Binding Name}"/>
<ListBox ItemsSource="{Binding lists}"/>
// DataViewModel.cs
public class DataViewModel
{
public int Id { get; set; } = 100;
public string Name { get; set; } = "特朗普";
public List<string> lists { get; set; } = new List<string>() { "金发", "商人", "川建国" };
}
8.3 代码动态添加数据
private void Window_Loaded(object sender, RoutedEventArgs e)
{
listbox.Items.Add("张三");
listbox.Items.Add("李四");
listbox.Items.Add("王五");
}
九、导航窗体
9.1 导航窗体结构
Window → NavigationWindow(导航窗体)
NavigationWindow 中包含多个 Page(页面)
9.2 设置导航窗体
<!-- 将 Window 改为 NavigationWindow -->
<NavigationWindow x:Class="项目名.MainWindow"
Source="Pages/MainPage.xaml"
ShowsNavigationUI="False">
<!-- ShowsNavigationUI="False" 隐藏默认导航箭头 -->
</NavigationWindow>
// Code-Behind 将 Window 改为 NavigationWindow
public partial class MainWindow : NavigationWindow
9.3 页面跳转
// 方式一:通过对象跳转
this.NavigationService.Navigate(new Page1());
// 方式二:通过 URI 跳转
this.NavigationService.Navigate(new Uri("pack://application:,,,/Pages/Page2.xaml"));
// 返回上一页
if (this.NavigationService.CanGoBack)
{
this.NavigationService.GoBack();
}
十、渐变(Brush)
10.1 线性渐变(LinearGradientBrush)
<Window.BorderBrush>
<LinearGradientBrush>
<GradientStopCollection>
<GradientStop Offset="0.0" Color="Red"/>
<GradientStop Offset="1.0" Color="Blue"/>
</GradientStopCollection>
</LinearGradientBrush>
</Window.BorderBrush>
10.2 径向渐变(RadialGradientBrush)
<Window.Background>
<RadialGradientBrush>
<GradientStopCollection>
<GradientStop Offset="0.0" Color="Red"/>
<GradientStop Offset="0.5" Color="Yellow"/>
<GradientStop Offset="1.0" Color="Pink"/>
</GradientStopCollection>
</RadialGradientBrush>
</Window.Background>
十一、用户控件(UserControl)
11.1 创建用户控件
- 继承自
UserControl 类。
- 包含独立的
.xaml 和 .xaml.cs 文件。
- 可以封装可复用的界面组件。
11.2 使用用户控件
<!-- 引入命名空间 -->
xmlns:uc="clr-namespace:项目名.UserControls"
<uc:UserControl1 Width="250" Height="180"/>
11.3 用户控件示例
<UserControl x:Class="项目名.UserControls.UserControl1" ...>
<Grid>
<Border BorderBrush="Red" Background="LightGray"
BorderThickness="3" CornerRadius="5">
<TextBlock Text="用户控件" FontWeight="Bold" FontSize="20"/>
</Border>
</Grid>
</UserControl>
十二、事件
12.1 路由事件分类
- 直接事件 :事件直接由触发事件的元素处理(如
Click)。
- 冒泡事件 :事件从内层标签向外层标签传播(如
MouseLeftButtonDown)。
- 隧道事件 :事件从外层标签向内层标签传播(如
PreviewMouseDown)。
12.2 常用事件
// 按钮点击事件
private void Button_Click(object sender, RoutedEventArgs e)
{
textblock1.Background = new SolidColorBrush(Colors.Green);
}
// 鼠标按下事件
private void Button_MouseDown(object sender, MouseButtonEventArgs e)
{
Window2 w2 = new Window2();
w2.ShowDialog();
}
// 选择改变事件
private void listbox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
MessageBox.Show(listbox.SelectedItem.ToString());
}
// 窗体加载事件
private void Window_Loaded(object sender, RoutedEventArgs e)
{
// 初始化逻辑
}
十三、颜色与十六进制
13.1 颜色表示
- 格式:
#RRGGBB(红、绿、蓝各 2 位,范围 00-FF)
- 示例:
#007aa4、#636366
13.2 颜色资源
<SolidColorBrush x:Key="s1" Color="#007aa4"/>
<x:Array x:Key="colors" Type="Color">
<Color>Red</Color>
<Color>Green</Color>
<Color>Blue</Color>
</x:Array>
十四、文本装饰
<TextBlock TextDecorations="Strikethrough"> 穿过文本 </TextBlock>
<TextBlock TextDecorations="Underline"> 下划线文本 </TextBlock>
TextDecorations 常用值:Strikethrough(删除线)、Underline(下划线)、OverLine(上划线)、Baseline(基线)。
十五、总结对比
| 知识点 |
关键点 |
| XAML |
标签即对象,属性即特性,内容区可嵌套 |
| 启动方式 |
StartupUri(简单)、Startup事件(灵活)、自定义Main(不推荐) |
| 布局 |
Grid(行列)、StackPanel(堆叠)、DockPanel(停靠)、WrapPanel(自动换行) |
| 样式 |
全局 > 局部 > 行内,支持 BasedOn 继承 |
| 资源 |
ResourceDictionary 可合并,支持多种数据类型 |
| 绑定 |
{StaticResource} 静态绑定,{Binding} DataContext 绑定 |
| 导航 |
NavigationWindow + Page,NavigationService 管理跳转 |
| 渐变 |
LinearGradientBrush(线性)、RadialGradientBrush(径向) |
| 用户控件 |
封装可复用的 UI 组件,通过 xmlns 引入 |
| 路由事件 |
直接、冒泡、隧道三种事件传播方式 |