I have defined a storyboard in the XAML source of a UserControl
. It is played whenever this function is called:
/// <summary>
/// Plays highlight animation.
/// </summary>
public void Highlight()
{
Storyboard highlighter = FindResource("Highlight") as Storyboard;
highlighter.Begin(this, true);
}
This works well as long as the animation isn't already playing when this function is called. When I call the function before the storyboard finishes playing, the animation gets stuck indefinitely. Why does this happen? Here is the source of the animation:
<Storyboard x:Key="Highlight" AutoReverse="True">
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="Border">
<EasingColorKeyFrame KeyTime="0:0:0.15" Value="LightGray">
<EasingColorKeyFrame.EasingFunction>
<ElasticEase EasingMode="EaseIn" Oscillations="1"/>
</EasingColorKeyFrame.EasingFunction>
</EasingColorKeyFrame>
</ColorAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)" Storyboard.TargetName="LayoutRoot">
<EasingDoubleKeyFrame KeyTime="0:0:0.15" Value="0.6">
<EasingDoubleKeyFrame.EasingFunction>
<ElasticEase EasingMode="EaseIn" Oscillations="1"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)" Storyboard.TargetName="LayoutRoot">
<EasingDoubleKeyFrame KeyTime="0:0:0.15" Value="0.6">
<EasingDoubleKeyFrame.EasingFunction>
<ElasticEase EasingMode="EaseIn" Oscillations="1"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
How do I make sure that the animation doesn't jam when the storyboard gets a new Begin
call before it finishes playing? I'm fine with either the animation restarting at each function call or no new animation being triggered while it is still playing. For whatever reason, this yields the exception Cannot perform action because the specified Storyboard was not applied to this object for interactive control:
Storyboard highlighter = FindResource("Highlight") as Storyboard;
if (highlighter.GetCurrentState(this) == ClockState.Stopped)
highlighter.Begin(this, true);
Update: I tried this XAML-based solution based on XAMIMAX's answer, but when I use this no animation is played whatsoever.
<UserControl.Triggers>
<EventTrigger RoutedEvent="local:StatusIcon.HighlightRequested">
<EventTrigger.EnterActions>
<BeginStoryboard x:Name="bidHighlight" Storyboard="{StaticResource Highlight}" />
</EventTrigger.EnterActions>
<EventTrigger.ExitActions>
<StopStoryboard BeginStoryboardName="bidHighlight" />
</EventTrigger.ExitActions>
</EventTrigger>
</UserControl.Triggers>