Storyboards can only be defined on root elements or as part of a style, even though every framework element has a Storyboard collection. The difference between setting the Storyboard attribute of the root element and setting the Storyboard attribute of a style can be summed up as follows:
Every Storyboard must have at least one SetterTimeline. A SetterTimeline describes the target of the animation and the attribute being animated. In order to animate an attribute, it must be a dependency property. Animation in XAML is accomplished by modifying the value of an attribute over time. A Path indicates the element and the attribute to modify. The Path is another name for the target of an animation . An example of this is (Button.Width) or (Button.Height).
The target is declared using the following syntax:
Example 6-1 shows the XAML for targeting the width of a button with an animation.
Example 6-1. Targeting an element in a SetterTimeline
Only framework elements can be targeted. Freezableselements deriving from the System.Windows.Freezable classcan only be targeted if they are used as an attribute value for another element. Brush is a freezable and is used to describe how to paint many attributes of elements, such as the Foreground and Background. Because Brush is used as the value of an attribute on an element, it can be targeted through the element, using syntax as follows:
An example of this is (Button.Background).(SolidColorBrush.Red), shown in Example 6-2.
Example 6-2. Targeting a Freezable in a SetterTimeline
If you are trying to target the attribute of an element that is part of a collection, you'll need to push the path even deeper:
An example of this is targeting a single transform inside the RenderTransform collection of a Rectangle. (Rectangle.RenderTransform).(TransformGroup.Children).(ScaleTransform.ScaleX) (Example 6-3).
Example 6-3. Targeting an element in a collection in a SetterTimeline
The type of the animation you add to the SetterTimeline must match the type of the attribute you are targeting. If you target a Color, then you must use a ColorAnimation. If the attribute is a Double, you must use a DoubleAnimation, and so on. If the attribute on the target is not declared, the animation has no effect. If you do not specify the Background color for Button, the animation does not appear to work.
In Example 6-4, a SetterTimeline that targets the Button myButton is declared. The Path of the SetterTimeline is set to the SolidColorBrush used to paint the Background of the Button. A ColorAnimation that changes the background color from blue to yellow is then added to the SetterTimeline. The Color begins as blue and, as specified by the Duration attribute of the ColorAnimation, will change to yellow within five seconds of the animation starting. The RepeatBehavior of the animation is declared as Forever, which means that once the animation ends, it will begin again, resetting the color to blue and continuing to iterate until the application closes.
Example 6-4. Animating the Background Color of a Button
All elements of TypeAnimation have a From, To, By, Duration, and RepeatBehavior attribute. The value of From, To, and By varies according to the type. A DoubleAni-mation, for example, requires Double values for these attributes . A RectAnimation requires a Rect, and so on. The animation starts at the value From and changes according to the To or By values. Setting the To attribute means that the animation value will move from the From value to the To value in the time period specified by Duration. Setting the By attribute means that the value will change by the By value during the time period specified by Duration. You are not allowed to set both the To and By attributes at the same time.
You determine the type of animation to use based on the attribute you are trying to animate. If you're animating the width of an element, use a DoubleAnimation because the data type of the Width attribute is a Double.
Example 6-5 shows the code used to animate the width of a Button using a DoubleAnimation. Over the course of five seconds, the Button will change width from 100 pixels to 200 pixels. Figures 6-1 through 6-4 illustrate the animation in effect at different times.
Example 6-5. Animating the width of a Button using DoubleAnimation
Figure 6-1. Animation of Button width at time 0:0:0
Figure 6-2. Animation of Button width at time 0:0:1
Figure 6-3. Animation of Button width at time 0:0:3
Figure 6-4. Animation of Button width at time 0:0:5
Once the animation completes (Figure 6-4), it returns to the beginning (Figure 6-1) and starts again, its width suddenly dropping from 200 to 100 in the process. There are mechanisms that allow you to change this behavior. Using attributes of the animation, you can expand the button's width and then reverse the animation so that it decreases its width gradually instead of returning to its original size. The next section discusses how to control different aspects of animations, such as speed and behavior.