WPF 学习总结
一、文本控件
RichTextBox 富文本控件
RichTextBox 用于显示和编辑富文本,内部使用 FlowDocument 排版内容。
<RichTextBox Width="200" HorizontalAlignment="Left">
<FlowDocument>
<!-- Paragraph:段落,LineHeight 行高,TextIndent 首行缩进 -->
<Paragraph LineHeight="20" TextIndent="20">
<!-- Run:显示纯文本 -->
<Run Text="防弹咖啡东方今典辅导费..."></Run>
</Paragraph>
<Paragraph>
<Run Foreground="Red" Text="红色文本"></Run>
</Paragraph>
<Paragraph>
<Run Foreground="Blue" Text="蓝色文本"></Run>
</Paragraph>
</FlowDocument>
</RichTextBox>
关键点:
- FlowDocument:流式容器,用于排版富文本,支持图文混排,类似于 Word 文档的流式布局
- Paragraph:段落,可设置
LineHeight(行高)、TextIndent(首行缩进) - Run:显示纯文本,可设置
Foreground等属性改变文本颜色
二、控件基础属性
Visibility 可见性
用于控制控件是否可见,有三个取值:
| 值 | 说明 |
|---|---|
Visible | 默认值,控件可见 |
Hidden | 隐藏控件,但仍然占据布局空间 |
Collapsed | 折叠控件,不占据布局空间 |
<Button Content="内容1" Visibility="Visible" />
Panel.ZIndex 层级关系
Panel.ZIndex 用于控制控件在 Z 轴(垂直屏幕方向)上的层级关系,Z 值越大,控件越靠上。
<Button Panel.ZIndex="2" Content="按钮2" Width="200" Height="200" HorizontalAlignment="Left" />
<StackPanel Panel.ZIndex="1" Background="Red">
<Button Content="内容1" />
</StackPanel>
三、变换(Transform)
RenderTransform 用于对控件进行渲染变换,WPF 提供四种基本变换类型:
| 变换类型 | 类名 | 说明 |
|---|---|---|
| 平移变换 | TranslateTransform | 移动控件位置,X 水平偏移,Y 垂直偏移 |
| 旋转变换 | RotateTransform | 旋转控件,Angle 旋转角度,CenterX/CenterY 变换中心 |
| 缩放变换 | ScaleTransform | 缩放控件,ScaleX 水平缩放,ScaleY 垂直缩放 |
| 倾斜变换 | SkewTransform | 倾斜控件,AngleX 水平倾斜,AngleY 垂直倾斜 |
示例:平移变换
<Rectangle Width="100" Height="30" Fill="Red">
<Rectangle.RenderTransform>
<TranslateTransform X="200" Y="10" />
</Rectangle.RenderTransform>
</Rectangle>
示例:旋转变换
<Rectangle Width="100" Height="30" Fill="Red">
<Rectangle.RenderTransform>
<RotateTransform Angle="45" CenterX="50" CenterY="15" />
</Rectangle.RenderTransform>
</Rectangle>
示例:缩放变换
<Rectangle Width="100" Height="30" Fill="Red">
<Rectangle.RenderTransform>
<ScaleTransform ScaleX="2" ScaleY="0.5" />
</Rectangle.RenderTransform>
</Rectangle>
示例:倾斜变换
<Rectangle Width="100" Height="30" Fill="Red">
<Rectangle.RenderTransform>
<SkewTransform AngleX="0" AngleY="30" />
</Rectangle.RenderTransform>
</Rectangle>
组合变换: 使用 TransformGroup 组合多个变换效果
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1.5" ScaleY="1.5" CenterX="50" CenterY="50" />
<RotateTransform Angle="30" CenterX="50" CenterY="50" />
</TransformGroup>
</Rectangle.RenderTransform>
四、样式(Style)
Style 用于定义控件的一组属性值,实现外观的统一管理。
基本语法
<Style x:Key="BorderStyle" TargetType="{x:Type Border}">
<!-- 使用 Setter 设置属性值 -->
<Setter Property="Background" Value="Green" />
<Setter Property="BorderBrush" Value="Red" />
</Style>
关键点:
x:Key:样式的唯一标识,用于引用TargetType:指定该样式应用于哪种控件类型Setter:设置属性值,包含Property(属性名)和Value(属性值)
使用样式
通过 StaticResource 或 DynamicResource 引用样式:
<Border Style="{StaticResource BorderStyle}" Height="100" Width="100" BorderThickness="4" />
| 引用方式 | 说明 |
|---|---|
StaticResource | 静态引用,在加载时解析,资源变化后不会更新 |
DynamicResource | 动态引用,在运行时解析,资源变化后会自动更新 |
五、触发器(Trigger)
触发器是 WPF 实现交互式样式的核心机制,允许在特定条件满足时自动改变控件的属性值。触发器定义在 Style.Triggers 或 ControlTemplate.Triggers 集合中。
1. Trigger 属性触发器
属性触发器:当控件的某个属性等于指定值时触发。
示例:Border 鼠标悬停改变背景和边框
<Style x:Key="BorderStyle" TargetType="{x:Type Border}">
<Style.Triggers>
<!-- 鼠标移入:背景变绿,边框变红 -->
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Green" />
<Setter Property="BorderBrush" Value="Red" />
</Trigger>
<!-- 鼠标移出:背景变白,边框变灰 -->
<Trigger Property="IsMouseOver" Value="False">
<Setter Property="Background" Value="White" />
<Setter Property="BorderBrush" Value="Gray" />
</Trigger>
</Style.Triggers>
</Style>
示例:鼠标悬停时触发变换效果
<Style x:Key="BorderStyle1" TargetType="{x:Type Border}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="RenderTransform">
<Setter.Value>
<TransformGroup>
<ScaleTransform ScaleX="1.5" ScaleY="1.5" CenterX="50" CenterY="50" />
<RotateTransform Angle="30" CenterX="50" CenterY="50" />
</TransformGroup>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsMouseOver" Value="False">
<Setter Property="RenderTransform">
<Setter.Value>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="1" CenterX="50" CenterY="50" />
<RotateTransform Angle="0" />
</TransformGroup>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
2. MultiTrigger 多条件触发器
多条件触发器:当多个条件同时满足时才触发样式变化。
<Style x:Key="TextBoxStyle" TargetType="TextBox">
<Setter Property="Foreground" Value="Black" />
<Style.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<!-- 条件1:鼠标悬停 -->
<Condition Property="IsMouseOver" Value="True" />
<!-- 条件2:获取焦点 -->
<Condition Property="IsFocused" Value="True" />
</MultiTrigger.Conditions>
<MultiTrigger.Setters>
<Setter Property="Background" Value="Red" />
</MultiTrigger.Setters>
</MultiTrigger>
</Style.Triggers>
</Style>
关键点:
<MultiTrigger.Conditions>中定义多个条件<MultiTrigger.Setters>中定义所有条件满足时执行的属性设置- 所有条件必须同时满足才会触发
3. EventTrigger 事件触发器
事件触发器:当某个路由事件(如 MouseEnter、MouseLeave)发生时触发,通常配合 Storyboard(动画板) 实现动画效果。
<Style x:Key="ButtonStyle" TargetType="Button">
<Style.Triggers>
<!-- 鼠标进入事件 -->
<EventTrigger RoutedEvent="MouseEnter">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Width"
From="100" To="300"
Duration="0:0:0.5" />
<ColorAnimation Storyboard.TargetProperty="Foreground.Color"
From="Yellow" To="Black"
Duration="0:0:1.0" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
<!-- 鼠标离开事件 -->
<EventTrigger RoutedEvent="MouseLeave">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Width"
From="300" To="100"
Duration="0:0:0.5" />
<ColorAnimation Storyboard.TargetProperty="Foreground.Color"
From="Black" To="Yellow"
Duration="0:0:0.5" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Style.Triggers>
</Style>
三种触发器对比:
| 类型 | 触发条件 | 典型应用 |
|---|---|---|
Trigger | 单个属性等于特定值 | 鼠标悬停改变颜色 |
MultiTrigger | 多个属性同时满足条件 | 鼠标悬停且获取焦点时改变背景 |
EventTrigger | 路由事件发生 | 鼠标进入/离开时运行动画 |
六、动画(Animation)
动画通过 Storyboard(动画板) 实现,配合 EventTrigger 使用。
动画类型
| 动画类 | 作用对象类型 | 典型属性 |
|---|---|---|
DoubleAnimation | double 类型属性 | Width、Height、Opacity、RenderTransform 等 |
ColorAnimation | 颜色类型属性 | Foreground、Background、BorderBrush 等 |
动画参数
| 参数 | 说明 |
|---|---|
Storyboard.TargetProperty | 指定要执行动画的属性名称 |
From | 动画起始值 |
To | 动画结束值 |
Duration | 动画持续时间,格式为 时:分:秒(如 0:0:0.5 表示 500 毫秒) |
动画结构
<EventTrigger RoutedEvent="MouseEnter">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<!-- 宽度从 100 到 300,持续 500ms -->
<DoubleAnimation Storyboard.TargetProperty="Width"
From="100" To="300"
Duration="0:0:0.5" />
<!-- 前景色从黄色到黑色,持续 1s -->
<ColorAnimation Storyboard.TargetProperty="Foreground.Color"
From="Yellow" To="Black"
Duration="0:0:1.0" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
七、控件模板(ControlTemplate)
1. 基本用法
ControlTemplate 用于定义控件的外观结构和视觉行为,决定控件"长什么样"以及"如何响应用户交互"。与 Style 不同,Style 只能修改控件的现有属性,而 ControlTemplate 可以完全重写控件的可视化树。
<ControlTemplate x:Key="ButtonTemplate1" TargetType="Button">
<!-- 使用 Border 作为容器 -->
<Border x:Name="border" Background="Red"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<StackPanel>
<CheckBox />
<CheckBox />
<!-- 内容呈现器:渲染控件外部设置的内容 -->
<ContentPresenter />
</StackPanel>
</Border>
<!-- 模板中的触发器 -->
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" TargetName="border" Value="Yellow" />
<Setter Property="BorderBrush" TargetName="border" Value="Blue" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
2. TemplateBinding 模板绑定
TemplateBinding 是控件模板中的标记扩展,用于将模板内部元素的属性绑定到使用该模板的控件的对应属性上,使用户在外部设置控件属性时能自动传递到模板内部元素。
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" />
3. ContentPresenter 内容呈现器
ContentPresenter 是控件模板中的内容占位符,负责渲染控件的内容(如 Button 的文本、图片等)。
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="{TemplateBinding Padding}"
RecognizesAccessKey="True"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
属性说明:
Focusable="False":不让内容区获取焦点,由外部控件统一管理RecognizesAccessKey="True":支持快捷键(如 Alt+字母)Margin="{TemplateBinding Padding}":绑定外层内边距作为内容外边距
4. 模板中的触发器
在 ControlTemplate.Triggers 中可以使用触发器,通过 TargetName 指定模板内部元素的名称。
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" TargetName="border" Value="Yellow" />
<Setter Property="BorderBrush" TargetName="border" Value="Blue" />
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter Property="Background" TargetName="border" Value="Red" />
<Setter Property="BorderBrush" TargetName="border" Value="Blue" />
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Background" TargetName="border" Value="Yellow" />
<Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="Gray" />
</Trigger>
</ControlTemplate.Triggers>
八、依赖属性(DependencyProperty)
概念
依赖属性 是 WPF 专门设计的属性系统,值存储在内部字典中,而非私有字段。依赖属性支持绑定、样式、动画、触发器等 WPF 核心功能。
普通属性与依赖属性的区别
| 特性 | 普通属性 | 依赖属性 |
|---|---|---|
| 值存储 | 私有字段 | 内部字典 |
| 支持绑定 | 不支持 | 支持 |
| 支持动画 | 不支持 | 支持 |
| 支持样式 | 不支持 | 支持 |
| 支持触发器 | 不支持 | 支持 |
依赖属性的组成
- CLR 包装器:标准的 .NET 属性封装,通过
GetValue/SetValue读写值 - 静态属性注册器:通过
DependencyProperty.Register注册,将属性注册到 WPF 属性系统中
语法结构
// 1. CLR 包装器
public CornerRadius CornerRadius
{
get { return (CornerRadius)GetValue(CornerRadiusProperty); }
set { SetValue(CornerRadiusProperty, value); }
}
// 2. 静态属性注册器
public static readonly DependencyProperty CornerRadiusProperty =
DependencyProperty.Register("CornerRadius", typeof(CornerRadius), typeof(MyButton));
Register 方法参数说明:
- 参数1:属性名称(字符串),必须与 CLR 包装器名称一致
- 参数2:属性类型
- 参数3:所属类的类型
- 参数4(可选):
PropertyMetadata设置默认值
带默认值的依赖属性
public string BaXian
{
get { return (string)GetValue(BaXianProperty); }
set { SetValue(BaXianProperty, value); }
}
public static readonly DependencyProperty BaXianProperty =
DependencyProperty.Register("BaXian", typeof(string), typeof(MyButton),
new PropertyMetadata("八仙")); // 设置默认值为 "八仙"
Visual Studio 快捷键: 输入 prodp 然后按 Tab 键,可快速生成依赖属性代码片段。
九、自定义控件
通过继承现有控件(如 Button)并添加依赖属性,可以创建自定义控件。
public class MyButton : Button
{
private int age; // 普通属性
public int Age { get; set; }
// 依赖属性:CornerRadius
public CornerRadius CornerRadius
{
get { return (CornerRadius)GetValue(CornerRadiusProperty); }
set { SetValue(CornerRadiusProperty, value); }
}
public static readonly DependencyProperty CornerRadiusProperty =
DependencyProperty.Register("CornerRadius", typeof(CornerRadius), typeof(MyButton));
// 依赖属性:BaXian(带默认值)
public string BaXian
{
get { return (string)GetValue(BaXianProperty); }
set { SetValue(BaXianProperty, value); }
}
public static readonly DependencyProperty BaXianProperty =
DependencyProperty.Register("BaXian", typeof(string), typeof(MyButton),
new PropertyMetadata("八仙"));
}
在 XAML 中使用自定义控件:
<!-- 引入命名空间 -->
<Window xmlns:c="clr-namespace:项目名.Controls">
<!-- 使用自定义控件 -->
<c:MyButton Template="{DynamicResource ButtonTemplate2}"
CornerRadius="200"
BaXian="钟离权" />
</Window>
在模板中绑定自定义控件的依赖属性:
<ControlTemplate x:Key="ButtonTemplate2" TargetType="{x:Type c:MyButton}">
<Border CornerRadius="{TemplateBinding CornerRadius}">
<StackPanel>
<CheckBox />
<CheckBox />
<TextBlock Text="{TemplateBinding BaXian}" />
<ContentPresenter />
</StackPanel>
</Border>
</ControlTemplate>
十、资源字典(ResourceDictionary)
ResourceDictionary 用于集中管理 WPF 资源(样式、模板、画刷等),支持跨文件合并。
合并资源字典
在 App.xaml 中合并多个资源字典文件:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Dictionary1.xaml" />
<ResourceDictionary Source="/Dictionary2.xaml" />
<ResourceDictionary Source="/Dictionary3.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
定义资源字典文件
<!-- Dictionary1.xaml -->
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!-- 定义颜色资源 -->
<SolidColorBrush x:Key="Button.Static.Background" Color="#FFDDDDDD" />
<SolidColorBrush x:Key="Button.Static.Border" Color="#FF707070" />
<!-- 定义样式 -->
<Style x:Key="ButtonStyle1" TargetType="{x:Type Button}">
<!-- ... -->
</Style>
<!-- 定义控件模板 -->
<ControlTemplate x:Key="ButtonTemplate1" TargetType="Button">
<!-- ... -->
</ControlTemplate>
</ResourceDictionary>
引用资源
| 引用方式 | 说明 |
|---|---|
StaticResource | 静态引用,在 XAML 加载时解析,资源变化后不会更新 |
DynamicResource | 动态引用,在运行时解析,资源变化后会自动更新 |
<Button Style="{StaticResource ButtonStyle1}" />
<Button Template="{DynamicResource ButtonTemplate1}" />
十一、总结与对比
核心概念对比
| 概念 | 作用 | 使用场景 |
|---|---|---|
| Style(样式) | 定义控件的一组属性值 | 统一设置控件的字体、颜色、大小等 |
| Trigger(触发器) | 条件满足时自动改变属性 | 鼠标悬停、获取焦点等交互效果 |
| ControlTemplate(控件模板) | 完全重写控件的外观结构 | 自定义按钮、输入框等控件的视觉样式 |
| DependencyProperty(依赖属性) | 支持绑定/动画/样式的属性系统 | 为自定义控件添加可交互的属性 |
| ResourceDictionary(资源字典) | 集中管理样式、模板等资源 | 跨页面共享资源,模块化管理 |
四种变换类型
| 变换 | 类名 | 关键属性 |
|---|---|---|
| 平移 | TranslateTransform | X, Y |
| 旋转 | RotateTransform | Angle, CenterX, CenterY |
| 缩放 | ScaleTransform | ScaleX, ScaleY, CenterX, CenterY |
| 倾斜 | SkewTransform | AngleX, AngleY |
三种触发器类型
| 类型 | 触发条件 | 典型应用 |
|---|---|---|
Trigger | 单个属性等于特定值 | 鼠标悬停改变颜色 |
MultiTrigger | 多个属性同时满足条件 | 鼠标悬停且获取焦点时改变背景 |
EventTrigger | 路由事件发生 | 鼠标进入/离开时运行动画 |
两种动画类型
| 动画类 | 作用属性 | 示例 |
|---|---|---|
DoubleAnimation | double 类型属性 | Width、Height、Opacity |
ColorAnimation | 颜色类型属性 | Foreground、Background |
547



被折叠的 条评论
为什么被折叠?



