问题描述
我在 UserControl
的 XAML 源中定义了一个故事板.每当调用此函数时都会播放它:
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>
当故事板在完成播放之前收到新的 Begin
调用时,我如何确保动画不会卡住?我对动画在每次函数调用时重新启动或在播放时没有触发新动画都很好.无论出于何种原因,这都会产生异常无法执行操作,因为指定的 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);
更新:我根据 XAMIMAX 的回答尝试了这个基于 XAML 的解决方案,但是当我使用它时,没有任何动画播放.
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>
推荐答案
当我在关键帧 0
为每个动画属性明确定义一个起始值时,我的问题就消失了.这是我的代码:
My problem went away when I explicitly defined a starting value for each animated property at keyframe 0
. Here is my code:
<Storyboard x:Key="Highlight" AutoReverse="True">
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="Border">
<EasingColorKeyFrame KeyTime="0" Value="White"/>
<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" Value="1"/>
<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" Value="1"/>
<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)[1].(SkewTransform.AngleX)" Storyboard.TargetName="LayoutRoot">
<EasingDoubleKeyFrame KeyTime="0" Value="1"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.15" Value="0"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[1].(SkewTransform.AngleY)" Storyboard.TargetName="LayoutRoot">
<EasingDoubleKeyFrame KeyTime="0" Value="1"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.15" Value="0"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
这篇关于对 storyboard.Begin(this, true) 的后续调用会干扰动画的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!