当前位置: 首页 > ai >正文

WPF 触发器 Trigger

触发器 Trigger

触发器(Trigger)是 WPF 中的一种机制:
当某个条件满足时,自动改变控件的某些属性,比如颜色、大小、透明度等。

换句话说,就是"如果……那么就……" 的一种规则。

常见触发器类型:

类型说明
Trigger依赖属性变化时触发
DataTrigger绑定的数据变化时触发
EventTrigger事件发生时触发
MultiTrigger多个条件同时满足时触发
MultiDataTrigger多个数据条件同时满足时触发


1. Trigger —— 属性值触发(最基础)

例如,当按钮被鼠标悬停(IsMouseOver = true)时,改变背景色:

<Button Content="鼠标悬停变色"><Button.Style><Style TargetType="Button"><Style.Triggers><Trigger Property="IsMouseOver" Value="True"> <!--Is... 触发条件--><Setter Property="Background" Value="LightGreen"/><Setter Property="Foreground" Value="DarkBlue"/></Trigger></Style.Triggers></Style></Button.Style>
</Button>

✅ 效果:鼠标悬停到按钮上时,按钮背景变绿、文字变蓝。

相关属性:

属性 / 子元素类型说明
PropertyDependencyProperty触发器监听的属性(比如 IsMouseOver
ValueobjectProperty 的值等于这个 Value 时触发
Setters集合(Setter满足条件后要应用的一组属性修改(比如改颜色、改大小)
EnterActions集合(TriggerAction当进入触发状态时执行的动作(比如动画)
ExitActions集合(TriggerAction当离开触发状态时执行的动作

常用条件:

属性触发器(PropertyTrigger)常用条件:

属性名说明
IsMouseOver鼠标悬停在控件上时为 True
IsPressed按钮等控件被按下时为 True
IsEnabled控件是否启用(禁用时为 False
IsFocused控件是否获得焦点(获取为 True)
IsChecked复选框(CheckBox)、单选按钮(RadioButton)是否选中
IsSelected列表项(ListBoxItem、TabItem等)是否被选中
Visibility控件是否可见(Visible / Hidden / Collapsed)
IsReadOnly文本框(TextBox)是否只读
OrientationStackPanel等控件的方向(Horizontal / Vertical)


2. DataTrigger —— 数据变化触发

当绑定的数据满足某条件时,触发样式改变。

例子:如果按钮绑定的某个值是 "危险",就变成红色。

<Button Content="按钮" Tag="危险"><Button.Style><Style TargetType="Button"><Style.Triggers><DataTrigger Binding="{Binding Tag, RelativeSource={RelativeSource Self}}" Value="危险"><Setter Property="Background" Value="Red"/></DataTrigger></Style.Triggers></Style></Button.Style>
</Button>

Tag 属性是 “危险” 时,按钮背景变红。

常用条件

DataTrigger 用于根据绑定到的数据(DataContext)变化触发,比如:

绑定属性说明
自定义属性值比如某个 ViewModel 中的 Status == "完成"
布尔型标志比如 IsLoading == true
数值型、字符串型比较比如 Level > 5(需要结合 Converter 实现)


3. EventTrigger —— 事件发生时触发动作(一般配合动画)

例子:当按钮加载完毕(Loaded 事件),让按钮慢慢变大:

<Button Content="加载放大按钮"><Button.Triggers><EventTrigger RoutedEvent="Button.Loaded"><BeginStoryboard> <!--动画--><Storyboard><DoubleAnimation Storyboard.TargetProperty="Width"From="100" To="200" Duration="0:0:2"/></Storyboard></BeginStoryboard></EventTrigger></Button.Triggers>
</Button>

✅ 效果:按钮出现后,2秒内宽度从100变到200。

主要属性

属性 / 子元素类型说明
RoutedEventRoutedEvent 类型要监听的事件(比如 Button.ClickEvent
SourceNamestring(可选)指定事件来源控件的名字(通常用于模板中)
Actions集合(TriggerAction事件触发时要执行的动作,通常是开始动画(BeginStoryboard
  1. RoutedEvent:必填!指定要监听哪个路由事件。
<!--当按钮被点击时触发。-->
<EventTrigger RoutedEvent="Button.Click">
  1. SourceName:(可选)指定事件来源控件的名字

    • 如果要监听的事件是来自模板中另一个控件,需要指定它的 x:Name

    • 通常用在 ControlTemplateDataTemplate 内。

<!--监听名为 `InnerBorder` 的元素的鼠标进入事件。-->
<EventTrigger RoutedEvent="MouseEnter" SourceName="InnerBorder">
  1. Actions:当事件发生时执行的动作。
    • BeginStoryboard:开始一个动画
    • StopStoryboard:停止一个动画
    • PauseStoryboard:暂停动画
    • ResumeStoryboard:恢复动画
<!--当事件触发时,执行透明度变化动画。-->
<BeginStoryboard><Storyboard><DoubleAnimation Storyboard.TargetProperty="Opacity" To="0.5" Duration="0:0:0.3"/></Storyboard>
</BeginStoryboard>


4. MultiTrigger —— 多属性同时满足触发

例子:按钮被禁用(IsEnabled = False)且鼠标悬停时,背景变灰:

<Button Content="多条件触发按钮" IsEnabled="False"><Button.Style><Style TargetType="Button"><Style.Triggers><MultiTrigger><MultiTrigger.Conditions><Condition Property="IsMouseOver" Value="True"/><Condition Property="IsEnabled" Value="False"/></MultiTrigger.Conditions><Setter Property="Background" Value="Gray"/></MultiTrigger></Style.Triggers></Style></Button.Style>
</Button>

✅ 效果:按钮同时满足两种状态,才改变样式。

相关属性

属性/子元素类型说明
Conditions集合(Condition定义多个条件,必须全部同时满足才触发
Setters集合(Setter满足条件后要改变的属性
EnterActions(可选)集合(TriggerAction进入触发状态时执行的动作(如动画)
ExitActions(可选)集合(TriggerAction离开触发状态时执行的动作
使用小技巧说明
尽量用 Style 包裹触发器让界面更整洁、好维护
配合 ControlTemplate自定义控件外观时,触发器更强大
Storyboard 让触发更有动效比如渐变色、放大缩小动画
http://www.xdnf.cn/news/4478.html

相关文章:

  • java每日精进 5.07【框架之数据权限】
  • 【C++游戏引擎开发】第33篇:物理引擎(Bullet)—射线检测
  • 小数的二进制表示
  • 【卡特兰数】不同的二叉搜索树
  • 学习笔记:黑马程序员JavaWeb开发教程(2025.3.30)
  • (25.05)Ubuntu 20.04上安装和运行ORB-SLAM3(非ROS)
  • 操作指南*
  • 数通HCIE的通过率怎么样?
  • no main manifest attribute, in xxx.jar
  • 软件系统的可观测性 Observability
  • 【AI】模型与权重的基本概念
  • 《Python星球日记》 第45天:KNN 与 SVM 分类器
  • 从电话到V信语音:一款App实现全场景社交脱身
  • 28.成功解决i2c_transfer返回-6的问题并linux驱动mpu6050(适合一切linux学习者)
  • OpenCV 中用于背景分割(背景建模)的一个类cv::bgsegm::BackgroundSubtractorCNT
  • 【HarmonyOS 5】鸿蒙中常见的标题栏布局方案
  • Oracle 开窗函数
  • 高组装导轨的特点
  • Java中字符转数字的原理解析 - 为什么char x - ‘0‘能得到对应数字
  • 《Python星球日记》 第43天:机器学习概述与Scikit-learn入门
  • 旧版谷歌浏览器Chrome v116.0.5845.141下载
  • 38.机壳间接缝的处理
  • 27、移除元素
  • 加速页面加载的全流程优化策略
  • 日常知识点之随手问题整理(虚函数 虚函数表 继承的使用场景)
  • 【Linux 系统调试】Linux 调试工具strip使用方法
  • Kubernetes生产级资源管理实战:从QoS策略到OOM防御体系
  • C 语言网络编程问题:E1696 无法打开 源 文件 “sys/socket.h“
  • ubuntu安装Go SDK
  • linux 怎么把trex-core-2.65用 crosstool-ng-1.27.0/编译