Note that in WPF all animations (element.BeginAnimation method) are executed asynchronously. So, if you call a bunch of BeginAnimation methods one after another in a for loop, they all will overlap and not really execute one after another.
There is really no way to chain animations in WPF. You will have to basically listen to an animation’s Completed event and then trigger the next animation. To make such code efficient and scalable I came up with this recursion with in-line event handler based approach:
Let us say you want to increase the width of these 2 rectangles one after the other via animation:
[XAML]
<Canvas>
<Rectangle x:Name='rect1' Canvas.Top='0' Width='30' Height='30' Fill='Aqua'></Rectangle>
<Rectangle x:Name='rect2' Canvas.Top='50' Width='30' Height='30' Fill='Azure'></Rectangle>
</Canvas>
The code-behind for this would be:
[C#]
private void Window_Loaded(object sender, RoutedEventArgs e)
{
DoubleAnimation da = new DoubleAnimation(100, new Duration(TimeSpan.FromSeconds(3)));
List list = new List();
list.Add(new object[] { rect1, Rectangle.WidthProperty, da});
list.Add(new object[] { rect2, Rectangle.WidthProperty, da });
this.PerformAnimations(0, list);
}
private void PerformAnimations(int index, List lstDefinitions)
{
object[] definition = lstDefinitions[index] as object[];
AnimationTimeline animation = definition[2] as AnimationTimeline;
animation.Completed += delegate
{
// Start the other animation after the end of the previous animation.
index++;
if (lstDefinitions.Count > index)
this.PerformAnimations(index, lstDefinitions);
};
((UIElement)definition[0]).BeginAnimation((DependencyProperty)definition[1], (AnimationTimeline)definition[2]);
}
The idea is to maintain a list of ‘animation definitiions’ and execute animations from this list recursively.
Permalink