My Problem:
When I try to handle a DoubleAnimation's Completed even the event does not fire if the animation was started by a DataTrigger. I am starting my event with a datatrigger because it must be started from the viewmodel. I have found that the Completed event will fire for an EventTrigger (like a button click). So I have created a simple example to show that the Completed event of a doubleanimation fires when it is triggered by another even (a button click) but not when it is triggered by a datatrigger. Why is this and/or how can I work around this behavior?
My Motivation (you can skip this)
I am trying to create a control that has 3 different states. When the control enters a state I would like it to perform an animation. I am have a lot of trouble getting it to repeat the animations more than once and I know this because an animation continues to act on the properties of the animation until it is removed. In order to remove the animation I wanted to create an event handler for the completed event of the animation. However, this event was not firing.
My Xaml
<Window x:Class="AnimationTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<DataTemplate x:Key="Control">
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding State}" Value="On">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="txtMessage"
Storyboard.TargetProperty="Opacity"
From="1.0" To="0.0" Duration="0:0:5"
Completed="DataTriggerAnimation_Completed" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
</DataTemplate.Triggers>
<DockPanel HorizontalAlignment="Center">
<StackPanel DockPanel.Dock="Bottom" Orientation="Horizontal">
<Button Content="Start Event Animation" x:Name="Button1" >
<Button.Background>
<SolidColorBrush x:Name="Button1BackgroundBrush" Color="Red" />
</Button.Background>
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="txtMessage"
Storyboard.TargetProperty="Opacity"
From="1.0" To="0.0" Duration="0:0:5"
FillBehavior="HoldEnd"
Completed="EventTriggerAnimation_Completed" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Button.Triggers>
</Button>
<Button Content="Data Animation" Click="Button_Click" />
</StackPanel>
<TextBlock x:Name="txtMessage" Text="{Binding Message}" />
</DockPanel>
</DataTemplate>
</Window.Resources>
<ContentPresenter ContentTemplate="{StaticResource Control}" Content="{Binding}" />
</Window>
Code Behind
public partial class MainWindow : Window
{
private MainWindowViewModel vm;
public MainWindow()
{
InitializeComponent();
vm = new MainWindowViewModel();
this.DataContext = vm;
}
private void DataTriggerAnimation_Completed(object sender, EventArgs e)
{
Console.WriteLine("Data Trigger Completed");
}
private void EventTriggerAnimation_Completed(object sender, EventArgs e)
{
Console.WriteLine("Event Trigger Completed");
}
private void Button_Click(object sender, RoutedEventArgs e)
{
vm.State = MainWindowViewModel.States.On;
}
}
My ViewModel
class MainWindowViewModel : INotifyPropertyChanged
{
private const string message = "This message is visible";
public string Message
{
get { return message; }
}
private States state;
public States State
{
get { return state; }
set
{
state = value;
OnPropertyChanged("State");
}
}
public enum States
{
Off,
On
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
PropertyChangedEventArgs e = new PropertyChangedEventArgs(propertyName);
handler(this, e);
}
}
#endregion
}
if you would like to download the project it is here https://dl.dropboxusercontent.com/u/104667143/AnimationTest.zip