Style中的Setter
Setter,设置器。Setter类的Property属性用来指名目标的属性, Value为其提供属性值,如果想设置控件的ControlTemplate,只需要把Setter的Property设为Template并为Value提供一个ControlTemplate对象即可。
Style中的Trigger
trigger,触发器。包括数据变化触发类型的Trigger/DataTrigger,多条件触发型的MultiTrigger/MultiDataTrigger及事件触发型的EventTrigger等。
- 基本Tirgger
Trigger类是最基本的触发器。类似于Setter,Trigger也有Property和Value,Property关注属性名称,Value是触发条件。Trigger类还一个Setters属性,是一组Setter,一旦触发条件满足,这组Setter的“属性——值”就被应用,触发条件不满足后,各属性值会被还原。
//CheckBox
<Style.Triggers>
<Trigger Property="IsChecked" Value="true">
<Setter Property="FontSize" Value="20" />
<Setter Property="Foreground" Value="Orange" />
</Trigger>
</Style.Triggers>
- MultiTrigger
多个条件同时成立时才会被触发。MultiTrigger比Trigger多一个Conditions属性,需要同时成立的条件就存储在这个集合中。
//CheckBox
<Style.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsChecked" Value="true" />
<Condition Property="Content" Value="正如我悄悄的来" />
</MultiTrigger.Conditions>
<MultiTrigger.Setters>
<Setter Property="FontSize" Value="20" />
<Setter Property="Foreground" Value="Orange" />
</MultiTrigger.Setters>
</MultiTrigger>
</Style.Triggers>
- 由数据触发的DataTrigger
基于数据执行某些判断情况,可以考虑使用DataTrigger。DataTrigger对象的Binding属性会把数据不断送过来,一旦送来的数据值与Value属性一致,DataTrigger即被触发。
下面例子中TextBox的Text长度小于7个字符是其Border保持红色。
<Style TargetType="TextBox">
<Style.Triggers>
<DataTrigger
Binding="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=Text.Length, Converter={StaticResource cvtr}}"
Value="false">
<Setter Property="BorderBrush" Value="Red" />
<Setter Property="BorderThickness" Value="1" />
</DataTrigger>
</Style.Triggers>
</Style>
//长度是一个具体数子,如何基于这个长度值做判断,就需要用到Converter,创建一个用于判断的Converter。
public class L2BConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
int textLength = (int)value;
return textLength > 6 ? true : false;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
DataTrigger的Binding。为了将控件自己作为数据源,我们用了RelativeSource,不明确指出Source时Binding会把控件的DataContext属性当做数据源,而非控件自身。
- 多数据条件触发的MultiDataTrigger
当需要多个数据条件同时满足时才能触发变化的需求时,可以考虑使用MultiDataTrigger。
比如用户界面上使用ListBox显示一列Student数据,当对象同时满足ID为2,Name为Tom是,条目就高亮显示。
<Style TargetType="ListBoxItem">
<!--使用Style设置DataTemplate-->
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Id}" Width="60"/>
<TextBlock Text="{Binding Name}" Width="120"/>
<TextBlock Text="{Binding Age}" Width="60"/>
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
<!--MultiDataTrigger-->
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Path=Id}" Value="2"/>
<Condition Binding="{Binding Path=Name}" Value="Tom"/>
</MultiDataTrigger.Conditions>
<MultiDataTrigger.Setters>
<Setter Property="Background" Value="Orange"/>
</MultiDataTrigger.Setters>
</MultiDataTrigger>
</Style.Triggers>
</Style>
效果图
5. 由事件触发的EventTrigger
被触发后并非一组Setter,而是执行一段动画,因此UI层动画动画效果往往与EventTrigger相关联。
下面例子中创建一个针对Button的Style,这个Style包含两个EventTrigger,一个由MouseEnter事件触发,另一个由MouseLeave事件触发:
<Window.Resources>
<Style TargetType="Button">
<Style.Triggers>
<!--鼠标进入-->
<EventTrigger RoutedEvent="MouseEnter">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation To="150" Duration="0:0:0.2" Storyboard.TargetProperty="Width"/>
<DoubleAnimation To="150" Duration="0:0:0.2" Storyboard.TargetProperty="Height"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<!--鼠标离开-->
<EventTrigger RoutedEvent="MouseLeave">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:0.2" Storyboard.TargetProperty="Width"/>
<DoubleAnimation Duration="0:0:0.2" Storyboard.TargetProperty="Height"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Canvas>
<Button Width="40" Height="40" Content="OK"/>
</Canvas>
效果图如下: