前置概念
触发器放在 Style.Triggers 内部,Style 触发器不能使用 TargetName ,只能修改控件自身属性。资源定义在Grid.Resources,通过StaticResource引用样式。
1. Trigger 属性触发器(单条件)
监控单个依赖属性,当属性等于指定 Value 时,执行 Setter 修改控件属性。
cs
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Orange"/>
</Trigger>
</Style.Triggers>
示例 1:BorderStyle
- 鼠标移入
IsMouseOver=True:背景橙色,边框绿色 - 鼠标移出
IsMouseOver=False:背景白色,边框灰色
示例 2:TextBlockStyle
- 鼠标悬浮:字号 30、斜体、文字黄色
- 鼠标离开:字号 12、正常字体、黑色文字
⚠️注意:
BorderStyle1存在代码 bug,连续两个 Setter 设置RenderTransform,后面的 RotateTransform 会直接覆盖前面 ScaleTransform,缩放效果失效,只会执行旋转。
cs
<!--错误写法,后面覆盖前面-->
<Setter Property="RenderTransform">
<Setter.Value>
<ScaleTransform ScaleX="1.5" ScaleY="1.5" CenterX="50" CenterY="50"></ScaleTransform>
</Setter.Value>
</Setter>
<!--直接覆盖上一个RenderTransform-->
<Setter Property="RenderTransform">
<Setter.Value>
<RotateTransform Angle="45" CenterX="50" CenterY="50"></RotateTransform>
</Setter.Value>
</Setter>
如果要同时缩放 + 旋转,需要使用
TransformGroup组合变换。
2. MultiTrigger 多条件触发器(全部条件同时满足才生效)
MultiTrigger.Conditions写一组条件,所有 Condition 必须同时成立,才执行 Setters 。 示例TextBoxStyle:
cs
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True"/> <!--鼠标悬浮-->
<Condition Property="IsFocused" Value="True"/> <!--获取输入焦点-->
</MultiTrigger.Conditions>
<MultiTrigger.Setters>
<Setter Property="Background" Value="Red"/>
</MultiTrigger.Setters>
</MultiTrigger>
逻辑:鼠标悬浮 AND 文本框获得焦点 → 背景变红;只要任意一个条件不满足,效果消失。
3. EventTrigger 事件触发器(触发路由事件,执行动画)
⚠️EventTrigger 不能直接写 Setter,只能执行动作,一般搭配
Storyboard故事板做动画。
RoutedEvent:指定路由事件,示例使用MouseEnter鼠标进入、MouseLeave鼠标离开EventTrigger.Actions:触发后执行行为,BeginStoryboard启动动画故事板DoubleAnimation:处理数值类型动画(字号、宽高、位移)ColorAnimation:处理颜色动画,注意路径Foreground.Color
cs
<EventTrigger RoutedEvent="MouseEnter">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<!--字号从12变化到30,持续0.5秒-->
<DoubleAnimation Storyboard.TargetProperty="FontSize" From="12" To="30" Duration="0:0:0.5"/>
<!--颜色动画,文字颜色从黄色变为黑色-->
<ColorAnimation Storyboard.TargetProperty="Foreground.Color" From="Yellow" To="Black" Duration="0:0:0.5"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
示例ButtonStyle:
- 鼠标移入按钮:字号放大、文字颜色渐变,动画时长 0.5 秒
- 鼠标移出按钮:字号缩小恢复、颜色还原
三种触发器对比
表格
| 触发器 | 作用 | 关键点 |
|---|---|---|
| Trigger | 单一属性条件 | 一个 Property=Value 条件,条件成立执行 Setter |
| MultiTrigger | 多条件 "与" 逻辑 | 所有 Conditions 必须同时满足才生效;是 AND 关系,不是 OR |
| EventTrigger | 路由事件触发动画 | 不支持 Setter;必须搭配 Storyboard 做动画;监听 MouseEnter、Loaded 等事件 |
重要坑点总结
- Style 内部触发器不能写 TargetName ,TargetName 仅在
ControlTemplate.Triggers控件模板触发器可用。 - 同一个属性多次 Setter 赋值,后面会直接覆盖前面,不能直接写多个 RenderTransform。
- MultiTrigger 是全部条件同时成立才触发,不是满足其中一个就触发。
- EventTrigger 只支持路由事件,不能直接修改属性,必须使用故事板动画。
- ColorAnimation 目标属性要写完整路径
Foreground.Color,不能直接写Foreground。
补充:同时缩放 + 旋转的修复代码(BorderStyle1 修正)
cs
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="RenderTransformOrigin" Value="0.5,0.5"/>
<Setter Property="RenderTransform">
<Setter.Value>
<TransformGroup>
<ScaleTransform ScaleX="1.5" ScaleY="1.5"/>
<RotateTransform Angle="45"/>
</TransformGroup>
</Setter.Value>
</Setter>
</Trigger>
拓展记忆:
- 属性触发器:监控属性值变化
- 多条件触发器:多个属性同时满足
- 事件触发器:监控事件发生,做动画