一.前言
使用触发器,可以动态的改变控件的外观,因为一些事件或属性改变了,把鼠标移动到按钮上,按钮就会改变其外观。通常这些必须写在C#代码中,使用WPF也可以使用XAMl实现,而这只会影响UI。
属性触发器在属性值改变时触发。多触发器多个属性,事件触发器在事件发生时激活,触发器在绑定数据的数据改变时触发。
二.属性触发器
Style类有一个Triggers属性,通过它可以指定属性触发器,下面的示例中有一个grid面板,利用window资源定义button元素的默认样式,这个样式指定,将Background属性设置为lightblue,将fontsize设置为17,这是应用程序启动时的样式,使用触发器可以改变控件的样式,触发器在Style.Triggers元素中用Trigger元素定义,将触发器赋予IsMouseOver属性,另一个触发器赋予IsPressed属性,如果触发这些属性,就会改变button的属性所对应的触发器属性。
<Window x:Class="WpfApp1.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:WpfApp1" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800"> <Window.Resources> <Style TargetType="Button"> <Setter Property="Background" Value="LightBlue"/> <Setter Property="FontSize" Value="17"/> <Style.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="Foreground" Value="Red"/> <Setter Property="FontSize" Value="22"/> </Trigger> <Trigger Property="IsPressed" Value="True"> <Setter Property="Foreground" Value="Yellow"/> <Setter Property="FontSize" Value="22"/> </Trigger> </Style.Triggers> </Style> </Window.Resources> <Grid> <Button Width="200" Height="30" Content="click me!!"></Button> </Grid> </Window>
其中需要注意的是,如果把IsPressed属性设置为true,则需要把IsMouseOver属性也设置为true;按下该按钮也需要吧鼠标放到按钮上,按下按钮会激活IsMouseOver属性触发器,并改变属性,这里触发器的激活顺序很重要,如果这两个触发器的顺序不同则会出现以下两种效果,请视图!如下。
? ? ?
当激活触发器的原因不再有效时,就不必要将属性重置为原始值了,例如,不必定义IsMuseOver=true和IsMouseOver=false的触发器,只要原因不在有效,就不会走了!
trigger类的属性,以指定触发器的操作.如下表:
Property Value? ? ? | 使用属性触发器,Property和Value属性用于指定触发器的激活时间,列如Property=“isMouseOver” Value="True" |
Setters | 一旦激活触发器,就可以使用Setters定义一个Setter元素集合,来改变属性值,其中定义了Property,targetname,value 来该对象属性。 |
EnterActions,ExitActions | 除了Setters之外,还可以定义EnterActions,ExitActions,这两个属性可以定义TriggerAction元素集合,使用这些可以操作派生自基类TriggerAction,如SoundPlayerAction和BeginStoryboard,使用SoundPlayerAction可以播放音乐。BeginStoryBoard用于动画 |
三.多触发器
当属性的值改变时,就会激活属性触发器,如果因为两个或多个属性有特定的值,而需要设置触发器,就可以使用MultiTrigger.
MultiTrigger有一个Conditions属性,可以在其中设置属性的有效值,它还有一个Setters属性,可以在其中指定需要设置的属性,在下面的示例中,给TextBox定义了样式,如果IsEnabled属性是True,那么Text属性的值是Test,就应用触发器。如果应用这两个触发器就把TextBox和Foreground属性改变为Red.
?
<Window x:Class="WpfApp1.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:WpfApp1" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800"> <Window.Resources> <Style TargetType="Button"> <Style.Triggers> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="IsMouseOver" Value="True"></Condition> <Condition Property="Content" Value="你好"></Condition> </MultiTrigger.Conditions> <MultiTrigger.Setters> <Setter Property="Foreground" Value="Red"/> </MultiTrigger.Setters> </MultiTrigger> </Style.Triggers> </Style> </Window.Resources> <Grid> <Button Margin="0,0,205,116" Content="你好"></Button> </Grid> </Window>
这代表了这个按钮只有在满足Codition这两个条件的时候才走Setters
三.数据触发器
如果绑定到控件上的数据满足指定的条件,就激活数据触发器,下面的示例中使用Book类,它根据图书的出版社显示不同的内容。
?Book.cs
?
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace WpfApp1 { public class Book { public string Title { get; set; } public string Publisher { get; set; } public override string ToString() => Title; } }
?
MainWindow.xaml
<Window x:Class="WpfApp1.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:WpfApp1" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800"> <Window.Resources> <Style TargetType="ListBoxItem"> <Style.Triggers> <DataTrigger Binding="{Binding Title}" Value="共赢"> <Setter Property="Background" Value="Red"/> </DataTrigger> <DataTrigger Binding="{Binding Title}" Value="努力"> <Setter Property="Background" Value="Yellow"/> </DataTrigger> <DataTrigger Binding="{Binding Title}" Value="学习"> <Setter Property="Background" Value="DarkGray"/> </DataTrigger> </Style.Triggers> </Style> </Window.Resources> <Grid> <ListBox x:Name="list"/> </Grid> </Window>
?后台代码中初始化几个Book对象,通过Binding中的定义就会给它进行格式化!
namespace WpfApp1 { /// <summary> /// MainWindow.xaml 的交互逻辑 /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); list.Items.Add(new Book { Publisher = "Zara带你去学习WPF", Title = "学习" }); list.Items.Add(new Book { Publisher = "Zara带你去学习WPF", Title = "勤奋" }); list.Items.Add(new Book { Publisher = "Zara带你去学习WPF", Title = "共赢" }); //重复数据 #region list.Items.Add(new Book { Publisher = "Zara带你去学习WPF", Title = "学习" }); list.Items.Add(new Book { Publisher = "Zara带你去学习WPF", Title = "勤奋" }); list.Items.Add(new Book { Publisher = "Zara带你去学习WPF", Title = "共赢" }); #endregion } } }
?今天我们就讲到这里,下一篇我们会深入触发器!