Información general sobre técnicas de animación de propiedades

En este tema se describen los enfoques diferentes para animar propiedades: guiones gráficos, animaciones locales, relojes y animaciones por fotograma.

Requisitos previos

Para entender este tema, debe estar familiarizado con las características de animación básicas descritas en Información general sobre animaciones.

Diferentes maneras de animar

Dado que hay muchos escenarios diferentes para animar propiedades, WPF proporciona varios enfoques para ello.

Para cada enfoque, en la tabla siguiente se indica si se puede usar por instancia, en estilos, en plantillas de control o en plantillas de datos; si se puede usar en XAML, y si el enfoque permite controlar interactivamente la animación. "Por instancia" se refiere a la técnica de aplicar directamente una animación o guión gráfico a las instancias de un objeto, en lugar de en un estilo, una plantilla de control o una plantilla de datos.

Técnica de animación Escenarios Admite XAML Control interactivo
Animación de guión gráfico Por instancia, Style, ControlTemplate, DataTemplate
Animación local Por instancia No No
Animación de reloj Por instancia No
Animación por fotograma Por instancia No N/D

Animaciones de guión gráfico

Use Storyboard cuando quiera definir y aplicar las animaciones en XAML, controlarlas de forma interactiva después de que empiecen, crear un árbol de animaciones complejo o animar en Style, ControlTemplate o DataTemplate. Para que un objeto se anime mediante Storyboard, debe ser FrameworkElement o FrameworkContentElement, o se debe usar para establecer FrameworkElement o FrameworkContentElement. Para obtener más detalles, consulte Información general sobre objetos Storyboard.

Storyboard es un tipo de contenedor Timeline especial que proporciona información de destino para las animaciones que contiene. Para animar con Storyboard, complete los siguientes tres pasos.

  1. Declare Storyboard y una o más animaciones.

  2. Use las propiedades adjuntas TargetName y TargetProperty para especificar el objeto y la propiedad de destino de cada animación.

  3. (Solo código) Defina NameScope para FrameworkElement o FrameworkContentElement. Registre los nombres de los objetos para animar con dicho FrameworkElement o FrameworkContentElement.

  4. Inicie Storyboard.

Iniciar Storyboard aplica animaciones a las propiedades que anima y las inicia. Hay dos formas de iniciar Storyboard: puede usar el método Begin proporcionado por la clase Storyboard o puede usar una acción BeginStoryboard. La única forma de animar en XAML es usar una acción BeginStoryboard. Una acción BeginStoryboard se puede usar en EventTrigger, una propiedad Trigger o en DataTrigger.

En la tabla siguiente se muestran los distintos espacios en los que se admite cada técnica de comienzo de Storyboard: por instancia, estilo, plantilla de control y plantilla de datos.

El guión gráfico se comienza utilizando... Por instancia Estilo Plantilla de control Plantilla de datos Ejemplo
BeginStoryboard y EventTrigger Animar una propiedad mediante un guión gráfico
BeginStoryboard y una propiedad Trigger No Activar una animación al cambiar el valor de una propiedad
BeginStoryboard y DataTrigger No Cómo: Activar una animación cuando se cambian datos
Método Begin No N.º No Animar una propiedad mediante un guión gráfico

Para más información sobre Storyboard, vea Información general sobre objetos Storyboard.

Animaciones locales

Las animaciones locales proporcionan una manera cómoda de animar una propiedad de dependencia de cualquier objeto Animatable. Las animaciones locales se utilizan cuando se desea aplicar una sola animación a una propiedad y no se necesita controlar interactivamente la animación después de iniciarse. Al contrario que una animación Storyboard, una animación local puede animar un objeto que no esté asociado a FrameworkElement o FrameworkContentElement. Tampoco es necesario definir NameScope para este tipo de animación.

Las animaciones locales únicamente se pueden utilizar mediante código y no se pueden definir en estilos, plantillas de control ni plantillas de datos. Una animación local no se puede controlar interactivamente una vez iniciada.

Para animar mediante una animación local, complete los pasos siguientes.

  1. Cree un objeto AnimationTimeline.

  2. Use el método BeginAnimation del objeto que quiera animar para aplicar AnimationTimeline a la propiedad que especifique.

En el ejemplo siguiente se muestra cómo animar el ancho y el color de fondo de Button.

/*

   This sample demonstrates how to apply non-storyboard animations to a property.
   To animate in markup, you must use storyboards.

*/

using namespace System;
using namespace System::Windows;
using namespace System::Windows::Navigation;
using namespace System::Windows::Media;
using namespace System::Windows::Media::Animation;
using namespace System::Windows::Shapes;
using namespace System::Windows::Controls;


namespace Microsoft {
   namespace Samples {
      namespace Animation {
         namespace LocalAnimations {
            // Create the demonstration.
            public ref class LocalAnimationExample : Page {

            public: 
               LocalAnimationExample ()
               {
                  WindowTitle = "Local Animation Example";
                  StackPanel^ myStackPanel = gcnew StackPanel();
                  myStackPanel->Margin = Thickness(20);

                  // Create and set the Button.
                  Button^ aButton = gcnew Button();
                  aButton->Content = "A Button";

                  // Animate the Button's Width.
                  DoubleAnimation^ myDoubleAnimation = gcnew DoubleAnimation();
                  myDoubleAnimation->From = 75;
                  myDoubleAnimation->To = 300;
                  myDoubleAnimation->Duration = Duration(TimeSpan::FromSeconds(5));
                  myDoubleAnimation->AutoReverse = true;
                  myDoubleAnimation->RepeatBehavior = RepeatBehavior::Forever;

                  // Apply the animation to the button's Width property.
                  aButton->BeginAnimation(Button::WidthProperty, myDoubleAnimation);

                  // Create and animate a Brush to set the button's Background.
                  SolidColorBrush^ myBrush = gcnew SolidColorBrush();
                  myBrush->Color = Colors::Blue;

                  ColorAnimation^ myColorAnimation = gcnew ColorAnimation();
                  myColorAnimation->From = Colors::Blue;
                  myColorAnimation->To = Colors::Red;
                  myColorAnimation->Duration = Duration(TimeSpan::FromMilliseconds(7000));
                  myColorAnimation->AutoReverse = true;
                  myColorAnimation->RepeatBehavior = RepeatBehavior::Forever;

                  // Apply the animation to the brush's Color property.
                  myBrush->BeginAnimation(SolidColorBrush::ColorProperty, myColorAnimation);
                  aButton->Background = myBrush;

                  // Add the Button to the panel.
                  myStackPanel->Children->Add(aButton);
                  this->Content = myStackPanel;
               };
            };
         }
      }
   }
}
/*

   This sample demonstrates how to apply non-storyboard animations to a property.
   To animate in markup, you must use storyboards.

*/

using System;
using System.Windows;
using System.Windows.Navigation;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Controls;

namespace Microsoft.Samples.Animation.LocalAnimations
{

    // Create the demonstration.
    public class LocalAnimationExample : Page
    {

        public LocalAnimationExample()
        {

            WindowTitle = "Local Animation Example";
            StackPanel myStackPanel = new StackPanel();
            myStackPanel.Margin = new Thickness(20);

            // Create and set the Button.
            Button aButton = new Button();
            aButton.Content = "A Button";

            // Animate the Button's Width.
            DoubleAnimation myDoubleAnimation = new DoubleAnimation();
            myDoubleAnimation.From = 75;
            myDoubleAnimation.To = 300;
            myDoubleAnimation.Duration =  new Duration(TimeSpan.FromSeconds(5));
            myDoubleAnimation.AutoReverse = true;
            myDoubleAnimation.RepeatBehavior = RepeatBehavior.Forever;

            // Apply the animation to the button's Width property.
            aButton.BeginAnimation(Button.WidthProperty, myDoubleAnimation);

            // Create and animate a Brush to set the button's Background.
            SolidColorBrush myBrush = new SolidColorBrush();
            myBrush.Color = Colors.Blue;

            ColorAnimation myColorAnimation = new ColorAnimation();
            myColorAnimation.From = Colors.Blue;
            myColorAnimation.To = Colors.Red;
            myColorAnimation.Duration =  new Duration(TimeSpan.FromMilliseconds(7000));
            myColorAnimation.AutoReverse = true;
            myColorAnimation.RepeatBehavior = RepeatBehavior.Forever;

            // Apply the animation to the brush's Color property.
            myBrush.BeginAnimation(SolidColorBrush.ColorProperty, myColorAnimation);
            aButton.Background = myBrush;

            // Add the Button to the panel.
            myStackPanel.Children.Add(aButton);
            this.Content = myStackPanel;
        }
    }
}
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'''This sample demonstrates how to apply non-storyboard animations to a property.
'''To animate in markup, you must use storyboards.
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Imports System.Windows
Imports System.Windows.Navigation
Imports System.Windows.Media
Imports System.Windows.Media.Animation
Imports System.Windows.Shapes
Imports System.Windows.Controls

Namespace Microsoft.Samples.Animation.LocalAnimations

    ' Create the demonstration.
    Public Class LocalAnimationExample
        Inherits Page

        Public Sub New()

            WindowTitle = "Animate Property Example"
            Dim myStackPanel As New StackPanel()
            myStackPanel.Margin = New Thickness(20)

            ' Create and set the Button.
            Dim aButton As New Button()
            aButton.Content = "A Button"

            ' Animate the Button's Width.
            Dim myDoubleAnimation As New DoubleAnimation()
            myDoubleAnimation.From = 75
            myDoubleAnimation.To = 300
            myDoubleAnimation.Duration = New Duration(TimeSpan.FromSeconds(5))
            myDoubleAnimation.AutoReverse = True
            myDoubleAnimation.RepeatBehavior = RepeatBehavior.Forever

            ' Apply the animation to the button's Width property.
            aButton.BeginAnimation(Button.WidthProperty, myDoubleAnimation)

            ' Create and animate a Brush to set the button's Background.
            Dim myBrush As New SolidColorBrush()
            myBrush.Color = Colors.Blue

            Dim myColorAnimation As New ColorAnimation()
            myColorAnimation.From = Colors.Blue
            myColorAnimation.To = Colors.Red
            myColorAnimation.Duration = New Duration(TimeSpan.FromMilliseconds(7000))
            myColorAnimation.AutoReverse = True
            myColorAnimation.RepeatBehavior = RepeatBehavior.Forever

            ' Apply the animation to the brush's Color property.
            myBrush.BeginAnimation(SolidColorBrush.ColorProperty, myColorAnimation)
            aButton.Background = myBrush

            ' Add the Button to the panel.
            myStackPanel.Children.Add(aButton)
            Me.Content = myStackPanel
        End Sub
    End Class
End Namespace

Animaciones de reloj

Use objetos Clock cuando quiera animar sin usar Storyboard y quiera crear árboles de tiempo complejos o controlar las animaciones de forma interactiva después de que empiecen. Puede usar objetos de Reloj para animar una propiedad de dependencia de cualquier objeto Animatable.

Los objetos Clock no se pueden usar directamente para animar en estilos, plantillas de control o plantillas de datos. (El sistema de animación y temporización realmente usa objetos Clock para animar en estilos, plantillas de control y plantillas de datos, pero debe crear esos objetos Clock a partir de un objeto Storyboard. Para obtener más información sobre la relación entre los objetos Storyboard y Clock, vea Información general sobre sistemas de temporización y animación).

Para aplicar un solo Clock a una propiedad, complete los pasos siguientes.

  1. Cree un objeto AnimationTimeline.

  2. Use el método CreateClock de AnimationTimeline para crear AnimationClock.

  3. Use el método ApplyAnimationClock del objeto que quiera animar para aplicar AnimationClock a la propiedad que especifique.

El siguiente ejemplo muestra cómo crear AnimationClock y aplicarlo a dos propiedades similares.

/*
    This example shows how to create and apply
    an AnimationClock.
*/

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Windows.Media.Animation;

namespace Microsoft.Samples.Animation.TimingBehaviors
{
    public class AnimationClockExample : Page
    {

        ScaleTransform myScaleTransform;

        public AnimationClockExample()
        {

            this.WindowTitle = "Opacity Animation Example";
            this.Background = Brushes.White;
            StackPanel myStackPanel = new StackPanel();
            myStackPanel.Margin = new Thickness(20);

            // Create a button that with a ScaleTransform.
            // The ScaleTransform will animate when the
            // button is clicked.
            Button myButton = new Button();
            myButton.Margin = new Thickness(50);
            myButton.HorizontalAlignment = HorizontalAlignment.Left;
            myButton.Content = "Click Me";
            myScaleTransform = new ScaleTransform(1,1);
            myButton.RenderTransform = myScaleTransform;

            // Associate an event handler with the
            // button's Click event.
            myButton.Click += new RoutedEventHandler(myButton_Clicked);

            myStackPanel.Children.Add(myButton);
            this.Content = myStackPanel;
        }

        // Create and apply and animation when the button is clicked.
        private void myButton_Clicked(object sender, RoutedEventArgs e)
        {

            // Create a DoubleAnimation to animate the
            // ScaleTransform.
            DoubleAnimation myAnimation =
                new DoubleAnimation(
                    1, // "From" value
                    5, // "To" value
                    new Duration(TimeSpan.FromSeconds(5))
                );
            myAnimation.AutoReverse = true;

            // Create a clock the for the animation.
            AnimationClock myClock = myAnimation.CreateClock();

            // Associate the clock the ScaleX and
            // ScaleY properties of the button's
            // ScaleTransform.
            myScaleTransform.ApplyAnimationClock(
                ScaleTransform.ScaleXProperty, myClock);
            myScaleTransform.ApplyAnimationClock(
                ScaleTransform.ScaleYProperty, myClock);
        }
    }
}
'
'    This example shows how to create and apply
'    an AnimationClock.
'


Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Media
Imports System.Windows.Shapes
Imports System.Windows.Media.Animation


Namespace Microsoft.Samples.Animation.TimingBehaviors
    Public Class AnimationClockExample
        Inherits Page

        Private ReadOnly myScaleTransform As ScaleTransform

        Public Sub New()

            WindowTitle = "Opacity Animation Example"
            Background = Brushes.White
            Dim myStackPanel As New StackPanel With {
                .Margin = New Thickness(20)
            }

                ' Create a button that with a ScaleTransform.
                ' The ScaleTransform will animate when the
                ' button is clicked.
            Dim myButton As New Button With {
                .Margin = New Thickness(50),
                .HorizontalAlignment = HorizontalAlignment.Left,
                .Content = "Click Me"
            }
            myScaleTransform = New ScaleTransform(1,1)
            myButton.RenderTransform = myScaleTransform


            ' Associate an event handler with the
            ' button's Click event.
            AddHandler myButton.Click, AddressOf myButton_Clicked

            myStackPanel.Children.Add(myButton)
            Content = myStackPanel
        End Sub

        ' Create and apply and animation when the button is clicked.
        Private Sub myButton_Clicked(sender As Object, e As RoutedEventArgs)

            ' Create a DoubleAnimation to animate the
            ' ScaleTransform.
            Dim myAnimation As New DoubleAnimation(1, 5, New Duration(TimeSpan.FromSeconds(5))) With {
                .AutoReverse = True
            } ' "To" value -  "From" value

            ' Create a clock the for the animation.
            Dim myClock As AnimationClock = myAnimation.CreateClock()

            ' Associate the clock the ScaleX and
            ' ScaleY properties of the button's
            ' ScaleTransform.
            myScaleTransform.ApplyAnimationClock(ScaleTransform.ScaleXProperty, myClock)
            myScaleTransform.ApplyAnimationClock(ScaleTransform.ScaleYProperty, myClock)
        End Sub
    End Class
End Namespace

Para crear un árbol de control de tiempo y utilizarlo para animar propiedades, complete los pasos siguientes.

  1. Use objetos ParallelTimeline y AnimationTimeline para crear el árbol de control de tiempo.

  2. Use CreateClock de la raíz ParallelTimeline para crear ClockGroup.

  3. Recorra en iteración Children de ClockGroup y aplique sus objetos secundarios Clock. Por cada elemento secundario AnimationClock, use el método ApplyAnimationClock del objeto que quiera animar para aplicar AnimationClock a la propiedad que especifique

Para más información acerca de los objetos de reloj, consulte Información general sobre sistemas de temporización y animación.

Animación por fotograma: omitir el sistema de animación y control de tiempo

Use este enfoque cuando necesite omitir completamente el sistema de animación de WPF. Un escenario para este enfoque lo constituyen las animaciones físicas, donde a cada paso de la animación es preciso volver a calcular los objetos basándose en el último conjunto de interacciones de objeto.

Las animaciones por fotograma no se pueden definir dentro de estilos, plantillas de control ni plantillas de datos.

Para animar fotograma a fotograma, se efectúa el registro para el evento Rendering del objeto que contiene los objetos que se desea animar. Se llama a este método de control de eventos una vez por cada fotograma. Cada vez que WPF serializa los datos de representación conservados en el árbol visual hasta el árbol de composición, se llama a este método de controlador de eventos.

En el controlador de eventos, realice los cálculos necesarios para el efecto de animación y establezca las propiedades de los objetos que desea animar con estos valores.

Para obtener el tiempo de presentación para el fotograma actual, la clase EventArgs asociada con este evento se puede convertir a RenderingEventArgs, que proporciona una propiedad RenderingTime que puede usar para obtener el tiempo de presentación del fotograma actual.

Para más información, consulte la página sobre Rendering.

Vea también