how to trigger a event handler when WPF animation repeated
I have a WPF animation with the RepeatBehavior set to Forever. There is something need be updated every time the animation is repeated. I can'开发者_JS百科t figure out how to catch the repeat event, the Complete event handler don't work for this. The animation interval is programmable and determined by some environmental factors. So use a timer isn't a neat approach. How can I do that?
Instead of having a RepeatBehavior of Forever, have it just run the one time, and catch the Completed event. Do your processing, and then call BeginAnimation using the proper DependencyProperty and animation.
For instance, here is a (admittedly silly) example to show what I mean.
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>
Code Behind:
private void changeColor3_Completed(object sender, EventArgs e)
{
Color3.BeginAnimation(GradientStop.ColorProperty, changeColor3);
}
Note that the Completed event is on the Storyboard, despite being declared in the animation. If you were to have RepeatForever set to true in some of the other animations, the event would never be fired.
I found a fairly elegant solution to this problem. It only requires adding an EventHandler to the CurrentTimeInvalidated
event on the Timeline
element:
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;
}
}
精彩评论