I’m trying to animate the ScaleY property of a LayoutTransform based on a DataTrigger bound to a boolean on my ViewModel class. The animation happens when the value is first seen to be false by the DataTrigger (when the application first starts) and when i first change it to true in a checkbox’s checked event but not when i set it to false in the same checkbox’s unchecked event.
A simplified version of what i’m doing is listed below.
The ViewModel class is very simple, containing a single boolean DependencyProperty called Selected.
public class VM : DependencyObject { public bool Selected { get { return (bool)GetValue(SelectedProperty); } set { SetValue(SelectedProperty, value); } } // Using a DependencyProperty as the backing store for Selected. This enables animation, styling, binding, etc... public static readonly DependencyProperty SelectedProperty = DependencyProperty.Register('Selected', typeof(bool), typeof(VM), new UIPropertyMetadata(false)); }
The Window.xaml contains a button and a checkbox. When the checkbox is checked, i set the ViewModel’s ‘Selected’ property to true and false when it is unchecked. Here’s the code for both the xaml and it’s code-behind.
<Window x:Class='DataTriggers.Window1' xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml' xmlns:y='clr-namespace:DataTriggers' Title='Window1' Height='300' Width='300'> <Window.Resources> <y:VM x:Key='VM'/> <Style TargetType='Button' x:Key='but'> <Style.Triggers> <DataTrigger Binding='{Binding Selected}' Value='False'> <DataTrigger.EnterActions> <BeginStoryboard> <Storyboard> <DoubleAnimation Duration='0:0:1' To='0' Storyboard.TargetProperty='(LayoutTransform).(ScaleTransform.ScaleY)'/> </Storyboard> </BeginStoryboard> </DataTrigger.EnterActions> </DataTrigger> <DataTrigger Binding='{Binding Selected}' Value='True'> <DataTrigger.EnterActions> <BeginStoryboard> <Storyboard> <DoubleAnimation Duration='0:0:1' To='1' Storyboard.TargetProperty='(LayoutTransform).(ScaleTransform.ScaleY)'/> </Storyboard> </BeginStoryboard> </DataTrigger.EnterActions> </DataTrigger> </Style.Triggers> </Style> </Window.Resources> <StackPanel> <Button Style='{StaticResource but}' DataContext='{StaticResource VM}'> <Button.LayoutTransform> <ScaleTransform></ScaleTransform> </Button.LayoutTransform> me </Button> <CheckBox Checked='CheckBox_Checked' Unchecked='CheckBox_Unchecked'/> </StackPanel>
public partial class Window1 : Window { public Window1() { InitializeComponent(); } private void CheckBox_Checked(object sender, RoutedEventArgs e) { VM vm = this.FindResource('VM') as VM; vm.Selected = true; } private void CheckBox_Unchecked(object sender, RoutedEventArgs e) { VM vm = this.FindResource('VM') as VM; vm.Selected = false; } }
I know that the DataTrigger fires when the property is false because if i change the DoubleAnimation to a simple Setter operating on the Opacity property then i see the correct results. So it would seem to be a problem with how I’m using the DoubleAnimation.
Any help would be appriciated.
This is ODD behavior but i decided to refactor the ‘False’ case into the DataTrigger’s ExitActions like this –
That works as intended. I don’t know what the difference is between the two cases but at least it’s an answer.