Windows Presentation Foundation

Hello, WPF

WPF from Scratch
Navigation Applications
Content Model
Layout
Controls
Data Binding
Dependency Properties
Resources
Styles and Control Templates
Graphics
Application Deployment
Where Are We?

Layout

Introduction
Layout Basics
DockPanel
StackPanel
Grid
Canvas
Viewbox
Text Layout
Common Layout Properties
When Content Doesn't Fit
Custom Layout
Where Are We?

Controls

Introduction
What Are Controls?
Handling Input
Built-In Controls
Where Are We?

Data Binding

Introduction
Without Data Binding
Data Binding
Binding to List Data
Data Sources
Master-Detail Binding
Where Are We?

Styles and Control Templates

Introduction
Without Styles
Inline Styles
Named Styles
Element-Typed Styles
Data Templates and Styles
Triggers
Control Templates
Where Are We?

Resources

Introduction
Creating and Using Resources
Resources and Styles
Binary Resources
Global Applications
Where Are We?

Graphics

Introduction
Graphics Fundamentals
Shapes
Brushes and Pens
Transformations
Visual-Layer Programming
Video and 3-D
Where Are We?

Animation

Animation Fundamentals
Timelines
Storyboards
Key Frame Animations
Creating Animations Procedurally
Where Are We?

Custom Controls

Introduction
Custom Control Basics
Choosing a Base Class
Custom Functionality
Templates
Default Visuals
Where Are We?

ClickOnce Deployment

A Brief History of Windows Deployment
ClickOnce: Local Install
The Pieces of ClickOnce
Publish Properties
Deploying Updates
ClickOnce: Express Applications
Choosing Local Install versus Express
Signing ClickOnce Applications
Programming for ClickOnce
Security Considerations
Where Are We?

 Animation Fundamentals


8.1. Animation Fundamentals

Animation involves changing some visible characteristic of a user interface, such as its size, position, or color, over some time period. You could do this the hard way, by creating a timer and modifying the user interface's appearance on each timer tick. Indeed, this is how animation is typically done in Win32 or Windows Forms. Fortunately, WPF takes care of these low-level details. Animation, like many features of WPF, simply requires us to declare what we would like done. The system takes care of doing it for us.

All of WPF's animation support boils down to changing one or more properties over time. This means that there are some limitations on what WPF's animation system can do for you. For example, the structure of the visual tree remains the same throughout. An animation will not add and remove elements for you (although it is possible for animation to set properties that will make elements invisible). There is no way of providing a "before" and "after" scene, or of getting WPF to interpolate between the two. This means there is no automatic way of animating a transition from one layout to another in such a way that the elements all slide from their start positions to their end positions.

The key to knowing what animation can or cannot do is to understand its property-focused natureit just changes whichever properties you tell it to. When deciding how to animate a UI, ask yourself what you would expect to see exactly halfway through the animation, and work out how the properties would need to be set in order to capture that halfway point. If you apply this thought process to animating from a horizontal to a vertical StackPanel, it's obvious that there's a problem. You can't set a property on a StackPanel to make it display something halfway between horizontal and vertical. And if you can't, neither can the animation system! (If you wanted to achieve this kind of effect, you would probably use a Canvas, as that allows arbitrary placement of elements. You would need to animate each element's position and size manually.)

Before we look at any of the parts of the animation framework in detail, let's examine a simple example. Example 8-1 shows the markup for a window containing a single red ellipse. The Ellipse element's Height is set to 100, but it does not declare a Width directly. Instead, the Width property is determined by an animationthe ellipse will change its width over time.

Example 8-1. A simple animation
<Window Text="Simple Animation" Width="320" Height="150"
    xmlns:x="http://schemas.microsoft.com/winfx/xaml/2005"
    xmlns="http://schemas.microsoft.com/winfx/avalon/2005">

    <Window.Storyboards>
        <SetterTimeline TargetName="myEllipse" Path="(Ellipse.Width)">
            <DoubleAnimation From="10" To="300" Duration="0:0:5"
                             RepeatBehavior="Forever" />
        </SetterTimeline>

    </Window.Storyboards>

    <Ellipse x:Name="myEllipse" Fill="Red" Height="100" />

</Window>

The animation is declared inside the Window.Storyboards property. A storyboard is a collection of animations and is used to coordinate multiple animations. When animations are defined in markup, they always appear inside storyboards, even in simple examples like this one where there is just one animation.

The animation in this example consists of two pieces, a SetterTimeline and a DoubleAnimation . The SetterTimeline determines what is to be animated through its TargetName property, which refers to the ellipse's x:Name property. Its Path property indicates that the ellipse's Width is to be animated.

The Path property needs the name of both the property to be animated and the class that defines the property. This is because properties do not always have to be defined by the class they are applied toyou might want to animate attached properties such as Canvas.Left. For consistency, you are required always to specify both class and property, even when the property is a member of the target object.


The DoubleAnimation nested inside the SetterTimeline determines how the animated property is to be changed over time. The significance of the "Double" in DoubleAnimation is that the property being animated is of type Double, as opposed to Int32, Point, Size, or some other type. Not all types are animated in the same way. For example, Point is a two-dimensional value, meaning we may want control over aspects of its animation that wouldn't make sense for a one-dimensional type like Double. The Ellipse.Width property we are animating here is of type Double, so we must use a DoubleAnimation.

Example 8-1 sets the From property to 10, the To property to 300, and the Duration property to 0:0:5. As you might guess, this means that the width will start at the value 10 and will gradually change to 300 over the course of 5 seconds. The RepeatBehavior property has been set to Forever, indicating that once the animation reaches the end, it should go back to the start and repeat indefinitely. Figure 8-1 shows how the ellipse appears at various stages during the animation.

Figure 8-1. Animation at start, after 2.5 seconds, and after 5 seconds


Make sure you specify all three parts of any duration value in an animation. The value 2 would be interpreted as 2 hours! If you meant 2 seconds, you must use 0:0:2, meaning 0 hours, 0 minutes, and 2 seconds.


As we will see, there are a number of ways of choosing exactly how the properties change, making it straightforward to support curved motion and changes in speed, but these are all just ways of getting WPF to set properties to the right value at the right time.

8.1.1. Animatable Properties

The majority of properties that have an impact on an element's appearance can be animated. There are just three requirements to be able to animate a property: the property must be a dependency property , a suitable animation type must be available, and the target element must derive from FrameworkElement.

The animation system relies on the dependency-property system to be able to update property values automatically. Chapter 9 describes dependency properties in detail. The majority of properties of WPF elements are dependency properties.

The second requirement, that the property's type must have a corresponding animation type, refers to types such as DoubleAnimation or PointAnimation . WPF supplies animation types for the majority of types used by properties that affect appearance. The main exceptions are enumeration types. For example, the Orientation type used by StackPanel has no corresponding animation type. This makes sense when you consider that this enumeration supports just two values, Horizontal and Vertical. There is no way to represent some intermediate value between these choices, so animation is not supported.

You can write your own animation types. This can be useful if you write a control that has properties of some custom type that you would like to animate. Technically, there is nothing stopping you writing an animation type for system types that do not support animation. For example, you could in theory write an OrientationAnimation. However, it would be of limited use, because at any given moment during the animation, it would be required to set the property to one of the two supported values: Horizontal or Vertical. There is no way of animating smoothly between these two values, so the best you could do is flip from one to the other partway through an animation.


The final requirement listed above is that the target element for animation must be a FrameworkElement. This is usually not a problem, because all WPF user-interface elements derive from this class. However, there will sometimes be quantities you may wish to animate that are not in fact properties of FrameworkElements, but which are nested properties of properties. For example, the ellipse in Example 8-1 is red, but we might want to animate this color. The Fill property's type is Brush, and the XAML compiler interprets the value of Red as shorthand for a SolidColorBrush property. (Brushes are discussed in detail in Chapter 7. The way that XAML converts strings to objects is discussed in Appendix A.) Example 8-2 shows the markup for the full versionthis is exactly equivalent to the one-line Ellipse declaration in Example 8-1.

Example 8-2. Ellipse with explicit SolidColorBrush
<Ellipse x:Name="myEllipse" Height="100">
    <Ellipse.Fill>
        <SolidColorBrush Color="Red" />
    </Ellipse.Fill>
</Ellipse>


This fully expanded version makes it clear that to change the ellipse's color over time, we need to animate the SolidColorBrush.Color property. But there's a problem. SolidColorBrush is not a FrameworkElement, because brushes are not a part of the user-interface tree. Brushes are very lightweight objects that describe how elements look, rather than being visible elements in their own right. You cannot assign an x:Name to a brush, and it cannot be the direct target of an animation.

This may seem like a rather severe restriction. Fortunately, a solution exists. An animation can target nested propertiesthe Path of a SetterTimeline can drill into sub-objects inside a property, and we can use that to animate properties of brushes and other similar lightweight types.

Example 8-3 shows how to animate the color of the ellipse.

Example 8-3. Animating nested properties
...
<Window.Storyboards>
    <SetterTimeline TargetName="myEllipse"
                    Path="(Ellipse.Fill).(SolidColorBrush.Color)">
        <ColorAnimation 
 Duration="0:0:7" From="Red" To="Purple"
                        RepeatBehavior="Forever" AutoReverse="True" />

    </SetterTimeline>
</Window.Storyboards>
...

The animation needs a FrameworkElement as its target, so its TargetName refers to the ellipse again. The SetterTimeline.Path property first identifies the Ellipse.Fill property and then indicates that it wants to drill into that property, which is a SolidColorBrush, and set the nested Color property. The ColorAnimation then specifies that the color should fade between red and purple every seven seconds.

If you are using the low-level geometry types described in Chapter 7 to build drawings, you will need to use the technique shown in Example 8-3, because Geometry does not derive from FrameworkElement. You can animate geometries inside the Data property of a Path by making the Path element the animation target and using the Path property of the SetterTimeline to specify properties on the geometry nested inside the Path. The same technique is also used to animate 3-D primitives.


SetterTimeline and the various animation types are all examples of timelines. Timelines are fundamental to animation, so we will now look at them in detail.



©2008 FAQ - WPF Labs - Discuss - Terms of Use - Privacy Policy - About WPF
- Interview Questions - Sharepoint Articles - Interview Questions Resource Library - All about LINQ - MS Knowledgebase Articles - Electronics and Hardware discussions