2014-03-05 56 views
4

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

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> 

EDIT 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' 

我发现关于它,including how to find what Storyboard caused the issueanother unanswered question几个StackOverflow的答案。

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

在这UserControl,我触发通过ControlStoryboardAction绑在LoadedEventTrigger故事板。这会使动画在加载时运行,并且它在UserControl的生命周期中只运行一次动画。我可以在XAML中使用动态值。下面是我如何删除和readding认为从它的父:

父视图:

<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); 
} 
+2

+1您的代码看起来是否正确...如果您在XAML中创建动画,它会正常工作吗? – BradleyDotNET

+0

我会试试看看会发生什么。 – jporcenaluk

+0

这可以在XAML中正常工作,但我使用的是动态属性,它位于ItemsControl中。我会编辑我的问题以提供更多信息。 – jporcenaluk

回答

0

您不能Value属性更改在运行时的方式你正在编辑之后。

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

要避开此限制,您需要在代码隐藏工作中完成部分或全部 工作。

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

那么你可能想回去的代码隐藏方法。

所以,作为一个最终的答案,我会做的是,当我想再次运行:

  • 删除以前的故事板
  • 创造出一个全新的故事板(或者只是动画)并运行它。
  • +0

    我的目标是每隔一段时间重复一次,而不是永远持续。我试图在创建故事板后,在完成后停止它,然后在没有这种运气的情况下重新开始故事板。 – jporcenaluk

    +0

    哦,在这种情况下......如果你是通过代码来完成的,只需做原始动画并跳过故事板。他们更容易管理。 –

    +0

    这是一个好主意。我找到了一种解决方法,但我会尝试一下,帮助未来的代码探索者。 – jporcenaluk

    相关问题