Общие сведения о методах анимации свойств

В этом разделе описываются различные подходы к анимации свойств: раскадровки, локальные анимации, часы и покадровая анимация.

Необходимые компоненты

Для понимания этого раздела необходимо ознакомиться с базовыми средствами анимации, которые описаны в разделе Общие сведения об эффектах анимации.

Различные способы анимации

Так как существует множество различных сценариев для анимации свойств, WPF предоставляет несколько подходов к анимации свойств.

Для каждого подхода в следующей таблице указано, можно ли применять его к конкретным экземплярам, использовать в стилях, в шаблонах элементов управления или в шаблонах данных, можно ли использовать его в XAML; и позволяет ли этот подход интерактивно управлять анимацией. Применение к конкретным экземплярам подразумевает применение анимации или раскадровки непосредственно к экземплярам объектов, а не в стилях, шаблонах элементов управления или шаблонах данных.

Подход к анимации Сценарии Поддерживает XAML Интерактивное управление
Раскадровка Применение к конкретным экземплярам, Style, ControlTemplate, DataTemplate Да Да
Локальная анимация Применение к конкретным экземплярам No No
Часы Применение к конкретным экземплярам No Да
Покадровая анимация Применение к конкретным экземплярам Нет Неприменимо

Раскадровка

Используйте Storyboard, если вы хотите определить и применить анимацию в XAML, интерактивно контролировать анимацию после ее запуска, создавать комплексное дерево анимации или анимировать в Style, ControlTemplate или DataTemplate. Чтобы объект был анимирован с помощью Storyboard, он должен быть FrameworkElement или FrameworkContentElement, или его необходимо использовать для задания FrameworkElement или FrameworkContentElement. Дополнительные сведения см. в разделе Общие сведения о раскадровке.

Storyboard - это специальные тип контейнера Timeline, предоставляющего целевую информацию для анимации, которая в нем содержится. Для создания анимации Storyboard нужно выполнить следующие три шага.

  1. Объявите Storyboard и один или несколько типов анимации.

  2. Используйте вложенные свойства TargetName и TargetProperty для указания целевого объекта и свойства каждой анимации.

  3. (Только код) Определите NameScope для FrameworkElement или FrameworkContentElement. Зарегистрируйте имена объектов для анимации с FrameworkElement или FrameworkContentElement.

  4. Запустите Storyboard.

Запуск Storyboard применяет анимацию к анимируемым свойствам и запускает ее. Есть два способа запуска Storyboard: можно использовать метод Begin, предоставляемый классом Storyboard, или действие BeginStoryboard. Единственный способ анимации в XAML - использовать действие BeginStoryboard. Действие BeginStoryboard можно использовать в EventTrigger, в свойстве Trigger или в DataTrigger.

В следующей таблице показано, где поддерживается каждый из методов запуска Storyboard: применение к конкретным экземплярам, в стилях, в шаблонах элементов управления и в шаблонах данных.

Раскадровка запускается с помощью метода... Применение к конкретным экземплярам Стиль Шаблон элемента управления Шаблон данных Пример
BeginStoryboard и EventTrigger Да Да Да Да Анимация свойства с помощью раскадровки
BeginStoryboard и свойство Trigger No Да Да Да Запуск анимации при изменении значения свойства
BeginStoryboard и DataTrigger No Да Да Да Практическое руководство. Запуск анимации при изменении данных
BeginМетод Да Нет Нет No Анимация свойства с помощью раскадровки

Дополнительные сведения об объектах Storyboard см. в разделе Общие сведения о раскадровках.

Локальная анимация

С помощью локальной анимации можно удобно анимировать свойство зависимостей любого объекта Animatable. Используйте локальную анимацию, когда необходимо применить одну анимацию к свойству и не требуется интерактивно управлять анимацией после ее запуска. В отличие от анимации Storyboard, локальная анимация может анимировать объект, не связанный с FrameworkElement или FrameworkContentElement. Для такой анимации вам также не нужно определять NameScope.

Локальные анимации могут использоваться только в коде. Их нельзя определить в стилях, шаблонах элементов управления и шаблонах данных. После запуска локальной анимации управлять ей в интерактивном режиме нельзя.

Для анимации с помощью локальной анимации выполните следующие действия.

  1. Создайте объект AnimationTimeline.

  2. Используйте метод BeginAnimation объекта, который вы хотите анимировать, чтобы применить AnimationTimeline к свойству, которое вы определяете.

В следующем примере показано, как анимировать ширину и цвет фона для 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

Часы

Используйте объекты Clock, если вы хотите создать анимацию без использования Storyboard и создать комплексные деревья тайминга или интерактивно управлять анимацией после ее запуска. Вы можете использовать объекты класса «Часы» для анимации свойства зависимостей объекта Animatable.

Объекты Clock нельзя использовать для непосредственной анимации в стилях, шаблонах элементов управления и шаблонах данных. (На самом деле система анимации и времени использует Clock объекты для анимации стилей, шаблонов элементов управления и шаблонов данных, но они должны создавать эти Clock объекты на основеStoryboard. Дополнительные сведения о связи между Storyboard объектами и объектами см. в разделе "Обзор системы анимации и Clock времени".)

Для применения одного Clock к свойству, выполните следующие шаги.

  1. Создайте объект AnimationTimeline.

  2. Используйте метод CreateClockAnimationTimeline для создания AnimationClock.

  3. Используйте метод ApplyAnimationClock объекта, который вы хотите анимировать, чтобы применить AnimationClock к свойству, которое вы определяете.

Следующий пример показывает, как создать AnimationClock и применить его к двум похожим свойствам.

/*
    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

Чтобы создать дерево временной шкалы и использовать его анимации свойств, выполните следующие действия.

  1. Используйте объекты ParallelTimeline и AnimationTimeline для создания дерева тайминга.

  2. Используйте CreateClock корня ParallelTimeline для создания ClockGroup.

  3. Выполните итерацию по ChildrenClockGroup и примените его дочерние объекты Clock. Для каждого дочернего элемента AnimationClock используйте метод ApplyAnimationClock объекта, который вы хотите анимировать, чтобы применить AnimationClock к свойству, которое вы определяете

Дополнительные сведения об объектах часов см. в разделе Общие сведения об анимации и системе управления временем.

Покадровая анимация: обход анимации и системы управления временем

Этот подход следует использовать, если требуется полностью обойти систему анимации WPF. Один из сценариев для такого подхода — анимация физики, при которой на каждом шаге анимации требуется пересчитывать объекты на основе последнего набора итераций объектов.

Покадровую анимацию нельзя определить в стилях, шаблонах элементов управления или шаблонах данных.

Чтобы создать покадровую анимацию, нужно зарегистрироваться для события Rendering объекта, содержащего объекты, которые нужно анимировать. Метод обработчика событий вызывается один раз для каждого кадра. Каждый раз, когда WPF выполняет маршалинг сохраненных данных отрисовки в визуальном дереве через дерево композиции, вызывается метод обработчика событий.

В обработчике событий выполняются все вычисления, необходимые для эффекта анимации, и задаются свойства объектов, которые требуется анимировать с этими значениями.

Чтобы получить время представления текущего кадра, можно привести объект EventArgs, связанный с этим событием, к классу RenderingEventArgs. Этот класс предоставляет свойство RenderingTime, с помощью которого можно получить время отрисовки текущего кадра.

Дополнительные сведения см. на Rendering странице.

См. также