为什么我的故事板只能运行一次



我有一个我想多次运行的故事表。不幸的是,在第一次运行之后,即使该代码被击中,它也不会再次动画。它只是第一次动画。我要设置一个初始值....即使我在重新运行之前设置该值。

DoubleAnimationUsingKeyFrames animateTransformX = new DoubleAnimationUsingKeyFrames();
EasingDoubleKeyFrame initialTransformXKeyframe = new EasingDoubleKeyFrame();
initialTransformXKeyframe.KeyTime = TimeSpan.FromSeconds(0);
//Resetting the value before running it again.
initialTransformXKeyframe.Value = 0;
animateTransformX.KeyFrames.Add(initialTransformXKeyframe);

EasingDoubleKeyFrame animateTransformXKeyframe = new EasingDoubleKeyFrame();
animateTransformXKeyframe.KeyTime = TimeSpan.FromSeconds(0.5);
animateTransformXKeyframe.Value = aDynamicValueGoesHere; 
animateTransformX.KeyFrames.Add(animateTransformXKeyframe);

Storyboard.SetTarget(animateTransformX, image);
Storyboard.SetTargetProperty(animateTransformX, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[0].(TranslateTransform.X)"));
Storyboard myStoryboard = new Storyboard();
myStoryboard.Children.Add(animateTransformX);
myStoryboard.Begin(this);

我觉得这很简单,但是对于我的一生,我不明白为什么。任何帮助将不胜感激。

编辑

我从CodeBehind那里这样做的原因是因为故事板是可冻结的,并且过去我遇到了麻烦,其中有动态的价值。为简单起见,我没有说我在代码中使用了动态值。我更新了上面的代码,以表明我正在使用动态值。

我尝试使用动态值将故事板作为XAML添加为XAML。如果使用非动态值,则可以正常工作(并重播),但仅在使用动态值时(首次)播放一次。

因此,例如,如果{Binding OffsetX}50替换,则可以重复使用。OffsetX通过实现INotifyPropertyChanged的属性进行更新。即使它是相同的,也从未更新,我认为它仍然应该是动画的,与以前的动画相同的值(就像50一样)。但事实并非如此;它只是不再动画。所以现在我真的迷路了。

<Storyboard x:Key="InitialAnimate">
    <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(TranslateTransform.X)" Storyboard.TargetName="StoryImage">
        <EasingDoubleKeyFrame KeyTime="0:0:0.6" Value="{Binding OffsetX}"/>
    </DoubleAnimationUsingKeyFrames>
</Storyboard>

编辑2

我没有解决这个问题,但是我找到了适合自己特定情况的解决方法。我在输出窗口中遇到了这个错误:

System.Windows.Media.Animation Warning: 6 : Unable to perform action because the specified Storyboard was never applied to this object for interactive control.; Action='Stop'; Storyboard='System.Windows.Media.Animation.Storyboard'; Storyboard.HashCode='28715394'; Storyboard.Type='System.Windows.Media.Animation.Storyboard'; TargetElement='System.Windows.Controls.Grid'; TargetElement.HashCode='6255521'; TargetElement.Type='System.Windows.Controls.Grid'

我找到了一些关于它的堆叠式答案,包括如何找到Storyboard引起的问题和另一个未解决的问题。

我仍然不确定如何解决我的原始问题,但这是我的解决方法。由于我只需要在重新启动时运行动画(在我的ViewModel中发生的事件),因此我使用在ViewModel中提出的事件并在父视图中消耗的事件来删除,然后重新添加包含动画的UserControl

在该UserControl中,我通过与Loaded EventTrigger绑定的ControlStoryboardAction触发了故事板。这使得动画在加载时运行,并且在UserControl的生命中,它只能运行动画一次。我能够在XAML中使用动态值。这是我从父母那里删除和读取视图的方式:

父视图:

<grid x:Name="imageHolder></grid>

父码:

private void CreateAnimations(object sender, EventArgs e)
{
    imageHolder.Children.RemoveAt(0);
    Views.Image image = new Image();
    image.Name = "image";
    imageHolder.Children.Add(image);
}

您无法按照编辑后的方式更改运行时的Value属性。

这是因为动画是可冻结的对象。还有更多 MSDN文档中的信息,但基本上意味着您 无法使用绑定,因为冷冻对象中的属性(即 动画)无法改变。

要解决此限制,您需要做一些或全部 在代码范围内工作。

查看为什么故事板值不会从资源或绑定中获得?

所以您可能想返回CodeBehind方法。

作为最终答案,我要做的是我想再次运行它:

  1. 删除以前的故事板
  2. 创建一个全新的故事板(或只是动画)并运行它。

最新更新