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

时间:2014-03-05 23:00:42

标签: c# .net wpf animation

我有一个故事板,我想多次运行。不幸的是,在第一次运行之后,即使这个代码被命中,它也不会再次生成动画。它只是第一次动画。我正在设置初始值....即使我在再次运行之前设置了值。

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);

我觉得这很简单,但对于我的生活,我无法理解为什么。任何帮助将不胜感激。

修改

我从代码隐藏中做这件事的原因是因为故事板是可以免费的,而且我过去遇到了动态值的麻烦。为简单起见,我没有说我在代码中使用了动态值;我更新了上面的代码,以显示我正在使用动态值。

我尝试使用动态值将故事板作为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'

我找到了一些关于它的StackOverflow答案,including how to find what Storyboard caused the issueanother unanswered question

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

UserControl中,我通过绑定到Loaded EventTrigger的{​​{3}}来触发故事板。这使得动画在加载时运行,并且它仅在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);
}

1 个答案:

答案 0 :(得分:0)

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

  

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

     

要解决这个限制,你需要做一些或全部   在代码隐藏中工作。

请参阅Why Storyboard value wouldn't get from a resource or binding?

所以你可能想回到codebehind方法。

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

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