2010-04-19 23 views
0

我有一个将RepeatBehavior设置为Forever的WPF动画。每次动画重复时都需要更新。我无法弄清楚如何捕捉重复事件,完整的事件处理程序不适用于此。动画间隔是可编程的,并由一些环境因素决定。所以使用定时器并不是一个整洁的方法。我怎样才能做到这一点?如何在重复WPF动画时触发事件处理程序

回答

0

而不是有一个永远的RepeatBehavior,让它只运行一次,并捕获Completed事件。执行处理,然后使用适当的DependencyProperty和动画调用BeginAnimation。

举例来说,这里是一个(确实有点傻)为例来说明我的意思。

XAML:

<TextBlock x:Name="txtExample" 
      Text="Gradients Are Neat" 
      FontSize="50"> 
    <TextBlock.Foreground> 
     <LinearGradientBrush x:Name="rgbForeground"> 
      <LinearGradientBrush.GradientStops> 

       <GradientStop x:Name="Color1" Color="#12BC23" Offset="0.0" /> 
       <GradientStop x:Name="Color2" Color="#AA0499" Offset="0.5" /> 
       <GradientStop x:Name="Color3" Color="#792BDF" Offset="1.0" /> 
      </LinearGradientBrush.GradientStops> 
     </LinearGradientBrush> 
    </TextBlock.Foreground> 
    <TextBlock.Triggers> 
     <EventTrigger RoutedEvent="TextBlock.Loaded"> 
      <EventTrigger.Actions> 
       <BeginStoryboard> 
        <Storyboard x:Name="SomeStoryboard"> 
         <ColorAnimation x:Name="changeColor1" 
             Storyboard.TargetName="Color1" 
             Storyboard.TargetProperty="Color" 
             Duration="0:0:3" 
             To="#81AD21"/> 
         <ColorAnimation x:Name="changeColor2" 
             Storyboard.TargetName="Color2" 
             Storyboard.TargetProperty="Color" 
             Duration="0:0:2" 
             To="#29910A"/> 
         <ColorAnimation x:Name="changeColor3" 
             Storyboard.TargetName="Color3" 
             Storyboard.TargetProperty="Color" 
             Duration="0:0:5" 
             To="#BB4923" 
             Completed="changeColor3JustOnce_Completed" /> 
        </Storyboard> 
       </BeginStoryboard> 
      </EventTrigger.Actions> 
     </EventTrigger> 
    </TextBlock.Triggers> 
</TextBlock> 

代码背后:

private void changeColor3_Completed(object sender, EventArgs e) 
{ 
    Color3.BeginAnimation(GradientStop.ColorProperty, changeColor3); 
} 

需要注意的是,在完成事件是在故事板,尽管在动画中被宣布。如果您在某些其他动画中将RepeatForever设置为true,则该事件永远不会被触发。

+0

这恰恰是我的方式。我使用相同的BeginTime和Duration定义了另一个动画,因为我不确定时序是否足够精确。目前它工作正常。谢谢。 – Hugo 2010-04-20 02:02:09

0

我发现了一个相当优雅的解决方案来解决这个问题。它只需要Timeline元素添加事件处理程序的CurrentTimeInvalidated事件:

private TimeSpan _lastTime; 

private void Animation_CurrentTimeInvalidated(object sender, EventArgs e) 
{ 
    var clock = sender as AnimationClock; 

    if (clock != null && clock.CurrentTime.HasValue) 
    { 
     if (clock.CurrentTime.Value < this._lastTime) 
     { 
      //TODO: Add any behavior to perform on a repeat here. 
     } 

     this._lastTime = clock.CurrentTime.Value; 
    } 
} 
相关问题