Przegląd Techniki animacji właściwości

W tym temacie opisano różne podejścia do animowania właściwości: scenorysy, animacje lokalne, zegary i animacje na ramkę.

Wymagania wstępne

Aby zrozumieć ten temat, należy zapoznać się z podstawowymi funkcjami animacji opisanymi w sekcji Przegląd animacji.

Różne sposoby animowania

Ze względu na to, że istnieje wiele różnych scenariuszy animowania właściwości, platforma WPF udostępnia kilka metod animowania właściwości.

Dla każdego podejścia poniższa tabela wskazuje, czy można go używać w poszczególnych wystąpieniach, w stylach, w szablonach kontrolek, czy w szablonach danych; czy można go używać w języku XAML; oraz to, czy podejście umożliwia interaktywną kontrolę animacji. Wyrażenie "Per-Instance" odnosi się do techniki stosowania animacji lub scenorysu bezpośrednio do wystąpień obiektu, a nie w stylu, szablonie kontrolki lub szablonie danych.

Technika animacji Scenariusze Obsługuje język XAML Interaktywnie sterowane
Animacja scenorysu Na wystąpienie, Style, , ControlTemplateDataTemplate Tak Tak
Animacja lokalna Na wystąpienie Nie. Nie.
Animacja zegara Na wystąpienie Nie. Tak
Animacja na ramkę Na wystąpienie Nie. Nie dotyczy

Animacje scenorysu

Użyj elementu Storyboard , jeśli chcesz zdefiniować i zastosować animacje w języku XAML, interakcyjnie kontrolować animacje po ich uruchomieniu, utworzyć złożone drzewo animacji lub animować w obiekcie StyleControlTemplate lub DataTemplate. Aby obiekt był animowany przez Storyboardelement , musi być elementem FrameworkElement lub FrameworkContentElementlub musi być używany do ustawiania FrameworkElement elementu lub FrameworkContentElement. Aby uzyskać więcej informacji, zobacz Storyboards Overview (Omówienie scenorysów).

A Storyboard to specjalny typ kontenera Timeline , który udostępnia informacje o określaniu wartości docelowej dla zawartych w nim animacji. Aby animować za pomocą elementu Storyboard, wykonaj następujące trzy kroki.

  1. Zadeklaruj jedną Storyboard lub więcej animacji.

  2. TargetName Użyj właściwości i TargetProperty dołączonych, aby określić obiekt docelowy i właściwość każdej animacji.

  3. (Tylko kod) Zdefiniuj element NameScope dla elementu FrameworkElement lub FrameworkContentElement. Zarejestruj nazwy obiektów, aby animować za pomocą tego FrameworkElement obiektu lub FrameworkContentElement.

  4. Rozpocznij .Storyboard

Rozpoczynanie Storyboard animacji stosuje się do właściwości, które animują i uruchamiają. Istnieją dwa sposoby rozpoczęcia Storyboardmetody : można użyć Begin metody dostarczonej Storyboard przez klasę BeginStoryboard lub użyć akcji. Jedynym sposobem animowania w języku XAML jest użycie BeginStoryboard akcji. BeginStoryboard Akcję można użyć w EventTriggerwłaściwości Trigger, lub DataTrigger.

W poniższej tabeli przedstawiono różne miejsca, w których jest obsługiwana każda Storyboard technika rozpoczęcia: na wystąpienie, styl, szablon kontrolki i szablon danych.

Scenorys zaczyna używać... Na wystąpienie Styl Szablon kontrolki Szablon danych Przykład
BeginStoryboard i EventTrigger Tak Tak Tak Tak Animowanie właściwości przy użyciu scenorysu
BeginStoryboard i właściwość Trigger Nie. Tak Tak Tak Wyzwalanie animacji w przypadku zmiany wartości właściwości
BeginStoryboard i a DataTrigger Nie. Tak Tak Tak Instrukcje: wyzwalanie animacji po zmianie danych
Begin Metoda Tak Nie Nie. Nie. Animowanie właściwości przy użyciu scenorysu

Aby uzyskać więcej informacji na temat Storyboard obiektów, zobacz Storyboards Overview (Omówienie scenorysów).

Animacje lokalne

Animacje lokalne zapewniają wygodny sposób animowania właściwości zależności dowolnego Animatable obiektu. Użyj lokalnych animacji, gdy chcesz zastosować pojedynczą animację do właściwości i nie musisz interakcyjnie kontrolować animacji po jej uruchomieniu. W przeciwieństwie do animacji animacja lokalna Storyboard może animować obiekt, który nie jest skojarzony z obiektem FrameworkElementFrameworkContentElementlub . Nie trzeba również definiować NameScope elementu dla tego typu animacji.

Animacje lokalne mogą być używane tylko w kodzie i nie mogą być zdefiniowane w stylach, szablonach kontrolek lub szablonach danych. Animacja lokalna nie może być interaktywnie kontrolowana po jej uruchomieniu.

Aby animować przy użyciu animacji lokalnej, wykonaj następujące kroki.

  1. Utwórz AnimationTimeline obiekt.

  2. BeginAnimation Użyj metody obiektu, który chcesz animować, aby zastosować AnimationTimeline właściwość do określonej właściwości.

W poniższym przykładzie pokazano, jak animować szerokość i kolor tła elementu 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

Animacje zegara

Używaj Clock obiektów, gdy chcesz animować bez użycia obiektu Storyboard i chcesz utworzyć złożone drzewa chronometrażu lub interaktywnie kontrolować animacje po ich uruchomieniu. Za pomocą obiektów Clock można animować właściwość zależności dowolnego Animatable obiektu.

Nie można używać Clock obiektów bezpośrednio do animowania w stylach, szablonach kontrolek lub szablonach danych. (System animacji i chronometrażu rzeczywiście używa Clock obiektów do animowania w stylach, szablonach kontrolek i szablonach danych, ale musi utworzyć te Clock obiekty na podstawie Storyboardelementu . Aby uzyskać więcej informacji na temat relacji między obiektami Storyboard i Clock obiektami, zobacz Animacja i System chronometrażu — omówienie.

Aby zastosować pojedynczy element Clock do właściwości, wykonaj następujące kroki.

  1. Utwórz AnimationTimeline obiekt.

  2. CreateClock Użyj metody , AnimationTimeline aby utworzyć obiekt AnimationClock.

  3. ApplyAnimationClock Użyj metody obiektu, który chcesz animować, aby zastosować AnimationClock obiekt do określonej właściwości.

W poniższym przykładzie pokazano, jak utworzyć obiekt AnimationClock i zastosować go do dwóch podobnych właściwości.

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

Aby utworzyć drzewo chronometrażu i użyć go do animowania właściwości, wykonaj następujące kroki.

  1. Użyj ParallelTimeline obiektów i AnimationTimeline , aby utworzyć drzewo chronometrażu.

  2. Użyj katalogu CreateClock głównego ParallelTimeline , aby utworzyć element ClockGroup.

  3. Iteruj przez obiekt ChildrenClockGroup i zastosuj jego obiekty podrzędne Clock . Dla każdego AnimationClock elementu podrzędnego użyj ApplyAnimationClock metody obiektu, który chcesz animować, aby zastosować AnimationClock obiekt do określonej właściwości

Aby uzyskać więcej informacji na temat obiektów zegara, zobacz Animacja i System chronometrażu — omówienie.

Animacja na ramkę: pomijanie animacji i systemu chronometrażu

Użyj tego podejścia, jeśli musisz całkowicie pominąć system animacji WPF. Jednym ze scenariuszy dla tego podejścia są animacje fizyki, w których każdy krok animacji wymaga ponownego skompilowania obiektów na podstawie ostatniego zestawu interakcji z obiektami.

Animacje dla ramki nie mogą być zdefiniowane wewnątrz stylów, szablonów kontrolek ani szablonów danych.

Aby animować ramkę po ramce, należy zarejestrować Rendering zdarzenie obiektu zawierającego obiekty, które mają być animowane. Ta metoda obsługi zdarzeń jest wywoływana raz na ramkę. Za każdym razem, gdy platforma WPF marshaluje utrwalone dane renderowania w drzewie wizualnym w drzewie kompozycji, wywoływana jest metoda obsługi zdarzeń.

W programie obsługi zdarzeń wykonaj dowolne obliczenia niezbędne dla efektu animacji i ustaw właściwości obiektów, które mają być animowane przy użyciu tych wartości.

Aby uzyskać czas prezentacji dla bieżącej ramki, EventArgs skojarzone z tym zdarzeniem można rzutować jako RenderingEventArgs, która udostępnia RenderingTime właściwość, której można użyć do uzyskania czasu renderowania bieżącej ramki.

Aby uzyskać więcej informacji, zobacz Rendering stronę.

Zobacz też