Archive

Posts Tagged ‘WPF Triggers’

WPF Triggers


There are three types of triggers:

· Property triggers— Invoked when the value of a dependency property changes

· Data triggers— Invoked when the value of a plain .NET property changes

· Event triggers— Invoked when a routed event is raised

Property Triggers

A property trigger (represented by the Trigger class) executes a collection of Setters when a specified property has a specified value. And when the property no longer has this value, the property trigger “undoes” the Setters.

For example, the following update to buttonStyle makes the rotation only happen when the mouse pointer is hovering over the Button (and sets the Foreground to Black rather than White):

<Style x:Key=”buttonStyle” TargetType=”{x:Type Button}”>

<Style.Triggers>

<Trigger Property=”IsMouseOver” Value=”True”>

<Setter Property=”RenderTransform”>

<Setter.Value>

<RotateTransform Angle=”10″/>

</Setter.Value>

</Setter>

<Setter Property=”Foreground” Value=”Black”/>

</Trigger>

</Style.Triggers>

<Setter Property=”FontSize” Value=”22″/>

<Setter Property=”Background” Value=”Purple”/>

<Setter Property=”Foreground” Value=”White”/>

<Setter Property=”Height” Value=”50″/>

<Setter Property=”Width” Value=”50″/>

<Setter Property=”RenderTransformOrigin” Value=”.5,.5″/>

</Style>

Data Triggers

Data triggers are just like property triggers, except that they can be triggered by any .NET property rather than just dependency properties. (The Setters inside a data trigger are still restricted to setting dependency properties, however.) To use a data trigger, add a DataTrigger object to the Triggers collection and specify the property/value pair. To support plain .NET properties, you specify the relevant property with a Binding rather than a simple property name. The following TextBox has a Style that triggers the setting of IsEnabled based on the value of its Text property, which is not a dependency property. When Text is the string “disabled,” IsEnabled is set to false (which is admittedly an unusual application of a data trigger):

<StackPanel Width=”200″>

<StackPanel.Resources>

<Style TargetType=”{x:Type TextBox}”>

<Style.Triggers>

<DataTrigger Binding=”{Binding RelativeSource={RelativeSource Self}, Path=Text}” Value=”disabled”>

<Setter Property=”IsEnabled” Value=”False”/>

</DataTrigger>

</Style.Triggers>

<Setter Property=”Background” Value=”{Binding RelativeSource={RelativeSource Self}, Path=Text}”/>

</Style>

</StackPanel.Resources> <TextBox Margin=”3″/>

</StackPanel>

Expressing More Complex Logic with Triggers The logic expressed with the previous triggers has been of the form “when property=value, set the following properties.” But more powerful options exist: · Multiple triggers can be applied to the same element (to get a logical OR). · Multiple properties can be evaluated for the same trigger (to get a logical AND).

Logical OR

Because Style.Triggers can contain multiple triggers, you can create more than one with the exact same Setters to express a logical OR relationship:

<Style.Triggers>

<Trigger Property=”IsMouseOver” Value=”True”>

<Setter Property=”RenderTransform”>

<Setter.Value>

<RotateTransform Angle=”10″/>

</Setter.Value>

</Setter>

<Setter Property=”Foreground” Value=”Black”/>

</Trigger>

<Trigger Property=”IsFocused” Value=”True”>

<Setter Property=”RenderTransform”>

<Setter.Value>

<RotateTransform Angle=”10″/>

</Setter.Value>

</Setter>

<Setter Property=”Foreground” Value=”Black”/>

</Trigger>

</Style.Triggers>

This means, “if IsMouseOver is true or if IsFocused is true, apply the rotation and black foreground.”

Logical AND

To express a logical AND relationship, you can use a variation of Trigger called MultiTrigger, or a variation of DataTrigger called MultiDataTrigger. MultiTrigger and MultiDataTrigger have a collection of Conditions that contain the information you would normally put directly inside a Trigger or DataTrigger. Therefore, you can use MultiTrigger as follows:

<Style.Triggers>

<MultiTrigger>

<MultiTrigger.Conditions>

<Condition Property=”IsMouseOver” Value=”True”/>

<Condition Property=”IsFocused” Value=”True”/>

</MultiTrigger.Conditions>

<Setter Property=”RenderTransform”>

<Setter.Value>

<RotateTransform Angle=”10″/>

</Setter.Value>

</Setter>

<Setter Property=”Foreground” Value=”Black”/>

</MultiTrigger>

</Style.Triggers>

This means, “if IsMouseOver is true and if IsFocused is true, apply the rotation and black foreground.” MultiDataTrigger works the same way as MultiTrigger, but with support for plain .NET properties.

EventTriggers

An event trigger (represented by the EventTrigger class) is activated when a routed event is raised. The event is specified by the trigger’s RoutedEvent property, and it can contain one or more actions (objects deriving from the abstract TriggerAction class) in its Actions collection. Animation classes such as DoubleAnimation are not actions themselves, so you can’t add them directly to an EventTrigger’s Actions collection. Instead, animations are placed inside an object known as a Storyboard, which is wrapped in an action called BeginStoryboard. Therefore, placing the preceding DoubleAnimation inside an event trigger that is activated when a Button is clicked can look as follows:

<Button> OK

<Button.Triggers>

<EventTrigger RoutedEvent=”Button.Click”>

<EventTrigger.Actions>

<BeginStoryboard>

<Storyboard TargetProperty=”Width”>

<DoubleAnimation From=”50″ To=”100″ Duration=”0:0:5″ AutoReverse=”True”/>

</Storyboard>

</BeginStoryboard>

</EventTrigger.Actions>

</EventTrigger>

</Button.Triggers>

</Button>

Categories: WPF Tags:
%d bloggers like this: