Event-based property changes in pure XAML
With XAML, the developer can easily edit an element and its attributes to adapt to a new situation or condition.
Join the DZone community and get the full member experience.
Join For FreeChanging properties in WPF is a thing that can be done in a matter of seconds. With XAML, the developer can easily edit an element and its attributes to adapt to a new situation or condition. It is a bit of a different approach when it comes to property modifications based on triggers.
Triggers in WPF are basically the “reasons” why some properties change. It can be a simple Trigger, that is a changed property itself causing another property to change, and then there is EventTrigger, that runs when an event occurs (consider it something similar to an event handler, although with a different implementation.
Let’s take a look how properties are being changed via regular Trigger elements:
<ControlTemplate.Triggers> <Trigger Property="Background" Value="White"> <Setter Property="Foreground" Value="Black" /> </Trigger></ControlTemplate.Triggers>
Notice that I am using a control template to test this functionality, but generally I am not referring to it (if at all), so don’t worry about the container for now.
As you see in my example, I have a Trigger element that sets off once the Background property of the referenced component is set to white. What it does, is set the Background property to Black. Pretty simple and straightforward – just the regular way to use a Setter element.
Now what about the EventTrigger? The natural way to think about the implementations is this:
<ControlTemplate.Triggers> <EventTrigger RoutedEvent="Button.Click"> <Setter Property="Foreground" Value="Black" /> </EventTrigger></ControlTemplate.Triggers>
However, by design, this will not work. There is a workaround, however, and it is tied to property change animation. A developer might think that he doesn’t want to see the property change animated – after all, he just wants to change the property and that’s it, no additional user experience elements. I considered this when working on the implementation.
Here is what it looks like:
<EventTrigger RoutedEvent="Button.Click"> <BeginStoryboard> <Storyboard> <ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetName="ButtonGrid" Storyboard.TargetProperty="Background"> <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource BlackBrush}" /> </ObjectAnimationUsingKeyFrames> </Storyboard> </BeginStoryboard></EventTrigger>
This example seems to be a little bit more complicated than the previous one, however, as you will see, in fact it isn’t so.
First of all, I am putting the actual event inside the Storyboard. A storyboard is something similar to the animation map – it contains the events and the time frames for them that are animated. Via the ObjectAnimationKeyFrame element I am defining the object that is being animated (in fact, I will only animate the specified property) and also the target property. The Duration attribute sets the animation duration to 0, therefore the user won’t be able to see any transitions – it will instantly change the property.
The DiscreteObjectKeyFrame defines the value of the target property for the specified timeframe. Notice the fact that this is a bit different from a Setter – I am only specifying the new value for the property, as the target is already defined.
The implementation I’ve showed is a pure XAML implementation. Of course, this can be done a bit easier in the code-behind, but I try to rely as much as possible on XAML when I am working with WPF.
Opinions expressed by DZone contributors are their own.
Comments