Although WPF animations are easy (see earlier post), that doesn't mean there aren't some tricky areas of animations you should be aware of. The WPF animation team and SDK just created a list of tips and tricks for working with animations that we will eventually be published on MSDN. Until then, you can see them here!
If you animate the position of a scroll bar or slider using an animation that has a FillBehavior of HoldEnd (the default value), the user will no longer be able to move the scroll bar or slider. That's because, even though the animation ended, it's still overriding the target property's base value. To stop the animation from overriding the property's current value, remove it, or give it a FillBehavior of Stop. For more information and an example, see How to: Set a Property After Animating It with a Storyboard.
You can't animate an object that is the output of another animation. For example, if you use an ObjectAnimationUsingKeyFrames to animate the Fill of a Rectangle from a RadialGradientBrush to a SolidColorBrush, you can't animate any properties of the RadialGradientBrush or SolidColorBrush.
In some cases, it might appear that you can't change the value of a property after it's been animated, even after the animation has ended. That's because, even though the animation ended, it's still overriding the property's base value. To stop the animation from overriding the property's current value, remove it, or give it a FillBehavior of Stop. For more information and an example, see How to: Set a Property After Animating It with a Storyboard.
Although most Timeline properties are animatable and can be data bound, changing the property values of an active Timeline seems to have no effect. That's because, when a Timeline is begun, the timing system makes a copy of the Timeline and uses it to create a Clock object. Modifying the original has no effect on the system's copy.
For a Timeline to reflect changes, its clock must be regenerated and used to replace the previously created clock. Clocks are not regenerated for you automatically. The following are several ways to apply timeline changes:
If the timeline is or belongs to a Storyboard, you can make it reflect changes by reapplying its storyboard using a BeginStoryboard or the Begin method. This has the side effect of also restarting the animation. In code, you can use the Seek method to advance the storyboard back to its previous position.
If you applied an animation directly to a property using the BeginAnimation method, call the BeginAnimation method again and pass it the animation that's been modified.
If you are working directly at the clock level, create and apply a new set of clocks and use them to replace the previous set of generated clocks.
For more information about timelines and clocks, see the Animation and Timing System Overview.
When you navigate away from a Page that contains running animations, those animations will continue to play until the Page is garbage collection. Depending on the navigation system you're using, a page that you navigate away from might stay in memory for an indefinite amount of time, all the while consuming resources with its animations. This is most noticeable when a page contains constantly running ("ambient") animations.
For this reason, it's a good idea to use the Unloaded event to remove animations when you navigate away from a page.
There are different ways to remove an animation. The following two techniques can be used to remove animations that belong to a Storyboard.
To remove a Storyboard you started with an event trigger, see How to: Remove a Storyboard.
To use code to remove a Storyboard, see the Remove method.
The next technique may be used regardless of how the animation was started.
To remove animations from a specific property, use the BeginAnimation method. Specify the property being animated as the first parameter, and null as the second. This will remove all animation clocks from the property.
For more information about the different ways to animate properties, see the Property Animation Techniques Overview.
When you apply a Storyboard, AnimationTimeline, or AnimationClock to a property using the Compose HandoffBehavior, any Clock objects previously associated with that property continue to consume system resources; the timing system will not remove these clocks automatically.
To avoid performance issues when you apply a large number of clocks using Compose, you should remove composing clocks from the animated property after they complete. There are several ways to remove a clock.
To remove all clocks from a property, use the ApplyAnimationClock or BeginAnimation method of the animated object. Specify the property being animated as the first parameter, and null as the second. This will remove all animation clocks from the property.
To remove a specific AnimationClock from a list of clocks, use the Controller property of the AnimationClock to retrieve a ClockController, then call the Remove method of the ClockController. This is typically done in the Completed event handler for a clock. Note that only root clocks can be controlled by a ClockController; the Controller property of a child clock will return null. Note also that the Completed event will not be called if the effective duration of the clock is forever. In that case, the user will need to determine when to call Remove.
This is primarily an issue for animations on objects that have a long lifetime. When an object is garbage collected, its clocks will also be disconnected and garbage collected.
For more information about clock objects, see the Animation and Timing System Overview.