分鏡腳本概觀Storyboards Overview

本主題說明如何使用Storyboard來組織和套用動畫的物件。This topic shows how to use Storyboard objects to organize and apply animations. 說明如何以互動方式操作Storyboard物件,並說明間接屬性目標語法。It describes how to interactively manipulate Storyboard objects and describes indirect property targeting syntax.

必要條件Prerequisites

若要了解本主題,您應該熟悉不同的動畫類型及其基本功能。To understand this topic, you should be familiar with the different animation types and their basic features. 如需動畫的簡介,請參閱動畫概觀For an introduction to animation, see the Animation Overview. 您也應該了解如何使用附加屬性。You should also know how to use attached properties. 如需附加屬性的詳細資訊,請參閱附加屬性概觀For more information about attached properties, see the Attached Properties Overview.

什麼是分鏡腳本?What Is a Storyboard?

動畫不是唯一有用的時間軸型別。Animations are not the only useful type of timeline. 還有其他時間軸類別可以協助您組織時間軸集合,以及將時間軸套用至屬性。Other timeline classes are provided to help you organize sets of timelines, and to apply timelines to properties. 容器時間軸衍生自TimelineGroup類別,並包含ParallelTimelineStoryboardContainer timelines derive from the TimelineGroup class, and include ParallelTimeline and Storyboard.

AStoryboard是一種容器時間軸,提供它所包含的時間軸目標資訊。A Storyboard is a type of container timeline that provides targeting information for the timelines it contains. 分鏡腳本可以包含任何類型的Timeline,包括其他容器時間軸和動畫。A Storyboard can contain any type of Timeline, including other container timelines and animations. Storyboard 物件可讓您結合成單一時間軸的樹狀結構,輕鬆地組織和控制複雜的計時行為的各種不同的物件和屬性會影響到的時間軸。Storyboard objects enable you to combine timelines that affect a variety of objects and properties into a single timeline tree, making it easy to organize and control complex timing behaviors. 例如,假設您想讓按鈕執行下列三個動作。For example, suppose you want a button that does these three things.

  • 在使用者選取按鈕時放大及變更色彩。Grow and change color when the user selects the button.

  • 按一下按鈕時縮小再放大回原本大小。Shrink away and then grow back to its original size when clicked.

  • 在停用時縮小並淡化到 50% 的不透明度。Shrink and fade to 50 percent opacity when it becomes disabled.

在此案例中,您有多組套用至同一個物件的動畫,並且想要視按鈕的狀態在不同時間播放。In this case, you have multiple sets of animations that apply to the same object, and you want to play at different times, dependent on the state of the button. Storyboard 物件可讓您組織動畫,並在群組中套用至一或多個物件。Storyboard objects enable you to organize animations and apply them in groups to one or more objects.

何處可以使用分鏡腳本?Where Can You Use a Storyboard?

AStoryboard可用來以動畫顯示相依性屬性的動畫類別 (如需有關如何使類別可用來建立動畫的詳細資訊,請參閱 < 動畫概觀)。A Storyboard can be used to animate dependency properties of animatable classes (for more information about what makes a class animatable, see the Animation Overview). 不過,因為分鏡腳本是架構層級的功能,該物件必須屬於NameScopeFrameworkElementFrameworkContentElementHowever, because storyboarding is a framework-level feature, the object must belong to the NameScope of a FrameworkElement or a FrameworkContentElement.

例如,您可以使用Storyboard執行下列動作:For example, you could use a Storyboard to do the following:

不過,您無法使用Storyboard來建立動畫SolidColorBrush並未註冊使用其名稱FrameworkElementFrameworkContentElement,或不用來設定的屬性FrameworkElementFrameworkContentElementHowever, you could not use a Storyboard to animate a SolidColorBrush that did not register its name with a FrameworkElement or FrameworkContentElement, or was not used to set a property of a FrameworkElement or FrameworkContentElement.

如何以分鏡腳本套用動畫How to Apply Animations with a Storyboard

若要使用Storyboard來組織和套用動畫,您必須將動畫加入為子時間軸StoryboardTo use a Storyboard to organize and apply animations, you add the animations as child timelines of the Storyboard. Storyboard類別會提供Storyboard.TargetNameStoryboard.TargetProperty附加屬性。The Storyboard class provides the Storyboard.TargetName and Storyboard.TargetProperty attached properties. 您可以設定動畫的這些屬性以指定其目標物件和屬性。You set these properties on an animation to specify its target object and property.

若要將動畫套用到其目標,請先Storyboard使用觸發程序動作或方法。To apply animations to their targets, you begin the Storyboard using a trigger action or a method. XAMLXAML,您使用BeginStoryboard物件EventTriggerTrigger,或DataTriggerIn XAMLXAML, you use a BeginStoryboard object with an EventTrigger, Trigger, or DataTrigger. 在程式碼中,您也可以使用Begin方法。In code, you can also use the Begin method.

下表顯示不同的地方,每個Storyboard開始技術支援: 每個執行個體、 樣式、 控制項範本以及資料範本。The following table shows the different places where each Storyboard begin technique is supported: per-instance, style, control template, and data template. 「每個執行個體」指的是將動畫或分鏡腳本直接套用至物件之執行個體,而非樣式、控制項範本或資料範本的技術。"Per-Instance" refers to the technique of applying an animation or storyboard directly to instances of an object, rather than in a style, control template, or data template.

開始分鏡腳本的方法…Storyboard is begun using… 每個執行個體Per-instance 樣式Style 控制項範本Control template 資料範本Data template 範例Example
BeginStoryboardEventTriggerBeginStoryboard and an EventTrigger Yes Yes Yes Yes 使用分鏡腳本建立屬性的動畫Animate a Property by Using a Storyboard
BeginStoryboard 和屬性 TriggerBeginStoryboard and a property Trigger No Yes Yes Yes 在屬性值變更時觸發動畫Trigger an Animation When a Property Value Changes
BeginStoryboardDataTriggerBeginStoryboard and a DataTrigger No Yes Yes Yes 如何:當資料變更時觸發動畫How to: Trigger an Animation When Data Changes
Begin 方法Begin method Yes No No No 使用分鏡腳本建立屬性的動畫Animate a Property by Using a Storyboard

下列範例會使用Storyboard來建立動畫WidthRectangle項目和ColorSolidColorBrush用來繪製, RectangleThe following example uses a Storyboard to animate the Width of a Rectangle element and the Color of a SolidColorBrush used to paint that Rectangle.

<!-- This example shows how to animate with a storyboard.-->
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  x:Class="Microsoft.Samples.Animation.StoryboardsExample" 
  WindowTitle="Storyboards Example">
  <StackPanel Margin="20">
    
    <Rectangle Name="MyRectangle"
      Width="100"
      Height="100">
      <Rectangle.Fill>
        <SolidColorBrush x:Name="MySolidColorBrush" Color="Blue" />
      </Rectangle.Fill>
      <Rectangle.Triggers>
        <EventTrigger RoutedEvent="Rectangle.MouseEnter">
          <BeginStoryboard>
            <Storyboard>
              <DoubleAnimation 
                Storyboard.TargetName="MyRectangle"
                Storyboard.TargetProperty="Width"
                From="100" To="200" Duration="0:0:1" />
              
              <ColorAnimation 
                Storyboard.TargetName="MySolidColorBrush"
                Storyboard.TargetProperty="Color"
                From="Blue" To="Red" Duration="0:0:1" />  
            </Storyboard>
          </BeginStoryboard>
        </EventTrigger>
      </Rectangle.Triggers>
    </Rectangle> 
  </StackPanel>
</Page>
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Data;
using System.Windows.Shapes;
using System.Windows.Input;


namespace Microsoft.Samples.Animation
{
    public class StoryboardsExample : Page
    {      
        public StoryboardsExample()
        {
            this.WindowTitle = "Storyboards Example";
            StackPanel myStackPanel = new StackPanel();
            myStackPanel.Margin = new Thickness(20);

            Rectangle myRectangle = new Rectangle();
            myRectangle.Name = "MyRectangle";
            
            // Create a name scope for the page.
            NameScope.SetNameScope(this, new NameScope());            
            
            this.RegisterName(myRectangle.Name, myRectangle);
            myRectangle.Width = 100;
            myRectangle.Height = 100;
            SolidColorBrush mySolidColorBrush = new SolidColorBrush(Colors.Blue);
            this.RegisterName("MySolidColorBrush", mySolidColorBrush);
            myRectangle.Fill = mySolidColorBrush;
            
            DoubleAnimation myDoubleAnimation = new DoubleAnimation();
            myDoubleAnimation.From = 100;
            myDoubleAnimation.To = 200;
            myDoubleAnimation.Duration = new Duration(TimeSpan.FromSeconds(1));
            Storyboard.SetTargetName(myDoubleAnimation, myRectangle.Name);
            Storyboard.SetTargetProperty(myDoubleAnimation, 
                new PropertyPath(Rectangle.WidthProperty));
            
            ColorAnimation myColorAnimation = new ColorAnimation();
            myColorAnimation.From = Colors.Blue;
            myColorAnimation.To = Colors.Red;
            myColorAnimation.Duration = new Duration(TimeSpan.FromSeconds(1));
            Storyboard.SetTargetName(myColorAnimation, "MySolidColorBrush");
            Storyboard.SetTargetProperty(myColorAnimation, 
                new PropertyPath(SolidColorBrush.ColorProperty)); 
            Storyboard myStoryboard = new Storyboard();
            myStoryboard.Children.Add(myDoubleAnimation);
            myStoryboard.Children.Add(myColorAnimation);

            myRectangle.MouseEnter += delegate(object sender, MouseEventArgs e)
            {
                myStoryboard.Begin(this);
            };
            
            myStackPanel.Children.Add(myRectangle);
            this.Content = myStackPanel;
        } 
    }
}

下列各節說明TargetNameTargetProperty更多詳細資料中的附加屬性。The following sections describe the TargetName and TargetProperty attached properties in more detail.

以架構元素、架構內容元素和 Freezable 為目標Targeting Framework Elements, Framework Content Elements, and Freezables

上一節提到,動畫若要尋找其目標,它必須知道目標的名稱和要建立動畫的屬性。The previous section mentioned that, for an animation to find its target, it must know the target's name and the property to animate. 指定要繪製之屬性很簡單: 只要設定Storyboard.TargetProperty要繪製之屬性的名稱。Specifying the property to animate is straight forward: simply set Storyboard.TargetProperty with the name of the property to animate. 指定您想要藉由設定以動畫顯示其屬性的物件名稱Storyboard.TargetName動畫的屬性。You specify the name of the object whose property you want to animate by setting the Storyboard.TargetName property on the animation.

針對TargetName屬性才能運作,目標的物件必須有名稱。For the TargetName property to work, the targeted object must have a name. 指派名稱給FrameworkElement或是FrameworkContentElementXAMLXAML不同於指派名稱給Freezable物件。Assigning a name to a FrameworkElement or a FrameworkContentElement in XAMLXAML is different than assigning a name to a Freezable object.

架構元素是繼承自這些類別FrameworkElement類別。Framework elements are those classes that inherit from the FrameworkElement class. 架構元素的範例包括WindowDockPanelButton,和RectangleExamples of framework elements include Window, DockPanel, Button, and Rectangle. 基本上所有的視窗、面板和控制項都是元素。Essentially all windows, panels, and controls are elements. 架構內容元素是繼承自這些類別FrameworkContentElement類別。Framework content elements are those classes that inherit from the FrameworkContentElement class. 架構內容元素的範例包括FlowDocumentParagraphExamples of framework content elements include FlowDocument and Paragraph. 如果您不確定某個型別是架構元素或架構內容元素,請檢查它是否具有 Name 屬性。If you're not sure whether a type is a framework element or a framework content element, check to see whether it has a Name property. 如果有,它可能是架構元素或架構內容元素。If it does, it's probably a framework element or a framework content element. 為了安全起見,請檢查其型別頁面的<繼承階層>一節。To be sure, check the Inheritance Hierarchy section of its type page.

若要啟用以架構元素或架構內容元素中的目標XAMLXAML,您將設定其Name屬性。To enable the targeting of a framework element or a framework content element in XAMLXAML, you set its Name property. 在程式碼中,您也需要使用RegisterName方法,以註冊項目的名稱與您已建立的項目NameScopeIn code, you also need to use the RegisterName method to register the element's name with the element for which you've created a NameScope.

下列範例中,從上述範例中,將名稱指派MyRectangle Rectangle,一種FrameworkElementThe following example, taken from the preceding example, assigns the name MyRectangle a Rectangle, a type of FrameworkElement.

<Rectangle Name="MyRectangle"
  Width="100"
  Height="100">
Rectangle myRectangle = new Rectangle();
myRectangle.Name = "MyRectangle";

// Create a name scope for the page.
NameScope.SetNameScope(this, new NameScope());            

this.RegisterName(myRectangle.Name, myRectangle);

在元素具有名稱後,您就可以為該元素的屬性建立動畫。After it has a name, you can animate a property of that element.

<DoubleAnimation 
  Storyboard.TargetName="MyRectangle"
  Storyboard.TargetProperty="Width"
  From="100" To="200" Duration="0:0:1" />
Storyboard.SetTargetName(myDoubleAnimation, myRectangle.Name);
Storyboard.SetTargetProperty(myDoubleAnimation, 
    new PropertyPath(Rectangle.WidthProperty));

Freezable 型別是繼承自Freezable類別。Freezable types are those classes that inherit from the Freezable class. 範例Freezable包括SolidColorBrushRotateTransform,和GradientStopExamples of Freezable include SolidColorBrush, RotateTransform, and GradientStop.

若要啟用的目標Freezable中的動畫所XAMLXAML,您使用X:name 指示詞將它指派名稱。To enable the targeting of a Freezable by an animation in XAMLXAML, you use the x:Name Directive to assign it a name. 在程式碼中,您會使用RegisterName方法,以註冊其名稱與您已建立的項目NameScopeIn code, you use the RegisterName method to register its name with the element for which you've created a NameScope.

下列範例會將指派的名稱Freezable物件。The following example assigns a name to a Freezable object.

<SolidColorBrush x:Name="MySolidColorBrush" Color="Blue" />
SolidColorBrush mySolidColorBrush = new SolidColorBrush(Colors.Blue);
this.RegisterName("MySolidColorBrush", mySolidColorBrush);

然後物件可以作為動畫的目標。The object can then be targeted by an animation.

<ColorAnimation 
  Storyboard.TargetName="MySolidColorBrush"
  Storyboard.TargetProperty="Color"
  From="Blue" To="Red" Duration="0:0:1" />  
Storyboard.SetTargetName(myColorAnimation, "MySolidColorBrush");
Storyboard.SetTargetProperty(myColorAnimation, 
    new PropertyPath(SolidColorBrush.ColorProperty)); 

Storyboard 物件會使用名稱範圍,來解決TargetName屬性。Storyboard objects use name scopes to resolve the TargetName property. 如需 WPF 名稱範圍的詳細資訊,請參閱 WPF XAML 名稱範圍For more information about WPF name scopes, see WPF XAML Namescopes. 如果TargetName省略屬性,動畫的元素,其定義所在,或在樣式中,該樣式的元素為目標。If the TargetName property is omitted, the animation targets the element on which it is defined, or, in the case of styles, the styled element.

有時候無法將名稱指派給Freezable物件。Sometimes a name can't be assigned to a Freezable object. 例如,如果Freezable是宣告為資源,或用來設定屬性值在樣式中,它不能指定名稱。For example, if a Freezable is declared as a resource or used to set a property value in a style, it can't be given a name. 因為它沒有名稱,就無法直接做為目標,但可間接做為目標。Because it doesn't have a name, it can't be targeted directly—but it can be targeted indirectly. 以下各節會說明如何使用間接目標。The following sections describe how to use indirect targeting.

間接目標Indirect Targeting

有些時候Freezable動畫,例如當無法直接目標Freezable是宣告為資源,或用來設定樣式中的屬性值。There are times a Freezable can't be targeted directly by an animation, such as when the Freezable is declared as a resource or used to set a property value in a style. 在這些情況下,即使您不能直接目標,但您可以仍然以動畫顯示Freezable物件。In these cases, even though you can't target it directly, you can still animate the Freezable object. 而不是設定TargetName屬性的名稱取代Freezable,您要提供它的項目名稱Freezable「 所屬 」。Instead of setting the TargetName property with the name of the Freezable, you give it the name of the element to which the Freezable "belongs." 例如,SolidColorBrush用來設定Fill之矩形的項目會屬於該矩形。For example, a SolidColorBrush used to set the Fill of a rectangle element belongs to that rectangle. 若要動畫顯示筆刷,您會設定動畫的TargetProperty以開始架構元素或架構內容元素的屬性的屬性鏈結Freezable用來設定,且結尾Freezable以動畫顯示屬性。To animate the brush, you would set the animation's TargetProperty with a chain of properties that starts at the property of the framework element or framework content element the Freezable was used to set and ends with the Freezable property to animate.

<ColorAnimation 
  Storyboard.TargetName="Rectangle01"
  Storyboard.TargetProperty="Fill.Color"
  From="Blue" To="AliceBlue" Duration="0:0:1" />
DependencyProperty[] propertyChain =
    new DependencyProperty[]
        {Rectangle.FillProperty, SolidColorBrush.ColorProperty};
string thePath = "(0).(1)";
PropertyPath myPropertyPath = new PropertyPath(thePath, propertyChain);
Storyboard.SetTargetProperty(myColorAnimation, myPropertyPath);

請注意,如果Freezable已凍結,將會進行複製,並以複製項目建立動畫。Note that, if the Freezable is frozen, a clone will be made, and that clone will be animated. 當發生這種情況,原始的物件HasAnimatedProperties屬性會繼續傳回false,因為原始的物件未實際以動畫顯示。When this happens, the original object's HasAnimatedProperties property continues to return false, because the original object is not actually animated. 如需有關複製的詳細資訊,請參閱Freezable 物件概觀For more information about cloning, see the Freezable Objects Overview.

另請注意,當使用間接屬性目標時,可能會以不存在的物件作為目標。Also note that, when using indirect property targeting, it's possible to target objects that don't exist. 例如,您可能會假設Background特定按鈕的設定SolidColorBrush,然後再試,以動畫顯示其色彩,當事實上LinearGradientBrush用來設定按鈕的背景。For example, you might assume that the Background of a particular button was set with a SolidColorBrush and try to animate its Color, when in fact a LinearGradientBrush was used to set the button's Background. 在這些情況下,會擲不回任何例外狀況;有可見效果,因為無法動畫LinearGradientBrush不會回應變更Color屬性。In these cases, no exception is thrown; the animation fails to have a visible effect because LinearGradientBrush does not react to changes to the Color property.

以下各節會詳細說明間接屬性目標語法。The following sections describe indirect property targeting syntax in more detail.

在 XAML 中以 Freezable 屬性為間接目標Indirectly Targeting a Property of a Freezable in XAML

中以 freezable 屬性為目標XAMLXAML,使用下列語法。To target a property of a freezable in XAMLXAML, use the following syntax.

ElementPropertyName . FreezablePropertyNameElementPropertyName . FreezablePropertyName

WhereWhere

下列程式碼示範如何建立動畫ColorSolidColorBrush用來設定The following code shows how to animate the Color of a SolidColorBrush used to set the

Fill 矩形元素。Fill of a rectangle element.

<Rectangle
  Name="Rectangle01"
  Height="100"
  Width="100"
  Fill="{StaticResource MySolidColorBrushResource}">
  <Rectangle.Triggers>
    <EventTrigger RoutedEvent="Rectangle.MouseEnter">
      <BeginStoryboard>
        <Storyboard>
          <ColorAnimation 
            Storyboard.TargetName="Rectangle01"
            Storyboard.TargetProperty="Fill.Color"
            From="Blue" To="AliceBlue" Duration="0:0:1" />
        </Storyboard>
      </BeginStoryboard>
    </EventTrigger>
  </Rectangle.Triggers>
</Rectangle>

有時候您需要以集合或陣列中包含的 Freezable 為目標。Sometimes you need to target a freezable contained in a collection or array.

若要以集合中包含的 Freezable 為目標,請使用下列路徑語法。To target a freezable contained in a collection, you use the following path syntax.

ElementPropertyName .Children[ CollectionIndex ]. FreezablePropertyNameElementPropertyName .Children[ CollectionIndex ]. FreezablePropertyName

何處CollectionIndex是其陣列或集合中物件的索引。Where CollectionIndex is the index of the object in its array or collection.

例如,假設矩形擁有TransformGroup資源套用至其RenderTransform屬性,而且您想要以動畫顯示它所包含的轉換的其中一個。For example, suppose that a rectangle has a TransformGroup resource applied to its RenderTransform property, and you want to animate one of the transforms it contains.

<TransformGroup x:Key="MyTransformGroupResource"
  x:Shared="False">
  <ScaleTransform />
  <RotateTransform />
</TransformGroup>

下列程式碼示範如何建立動畫Angle屬性RotateTransform先前範例所示。The following code shows how to animate the Angle property of the RotateTransform shown in the previous example.

<Rectangle
  Name="Rectangle02"
  Height="100"
  Width="100"
  Fill="Blue"
  RenderTransform="{StaticResource MyTransformGroupResource}">
  <Rectangle.Triggers>
    <EventTrigger RoutedEvent="Rectangle.MouseEnter">
      <BeginStoryboard>
        <Storyboard>
          <DoubleAnimation 
            Storyboard.TargetName="Rectangle02"
            Storyboard.TargetProperty="RenderTransform.Children[1].Angle"
            From="0" To="360" Duration="0:0:1" />
        </Storyboard>
      </BeginStoryboard>
    </EventTrigger>
  </Rectangle.Triggers>
</Rectangle>  

在程式碼中以 Freezable 的屬性為間接目標Indirectly Targeting a Property of a Freezable in Code

在程式碼中,您會建立PropertyPath物件。In code, you create a PropertyPath object. 當您建立PropertyPath,您指定PathPathParametersWhen you create the PropertyPath, you specify a Path and PathParameters.

若要建立PathParameters,建立型別的陣列DependencyProperty,其中包含一份相依性屬性識別碼欄位。To create PathParameters, you create an array of type DependencyProperty that contains a list of dependency property identifier fields. 第一次的識別項欄位代表的屬性FrameworkElement或是FrameworkContentElementFreezable用來設定。The first identifier field is for the property of the FrameworkElement or FrameworkContentElement that the Freezable is used to set. [下一步] 的 [識別碼] 欄位表示的屬性Freezable為目標。The next identifier field represents the property of the Freezable to target. 把它想成連接屬性的一連串FreezableFrameworkElement物件。Think of it as a chain of properties that connects the Freezable to the FrameworkElement object.

以下是範例的目標相依性屬性鏈結ColorSolidColorBrush用以設定Fill矩形元素。The following is an example of a dependency property chain that targets the Color of a SolidColorBrush used to set the Fill of a rectangle element.

DependencyProperty[] propertyChain =
    new DependencyProperty[]
        {Rectangle.FillProperty, SolidColorBrush.ColorProperty};

您也需要指定PathYou also need to specify a Path. APathString告訴Path如何解譯其PathParametersA Path is a String that tells the Path how to interpret its PathParameters. 它會使用下列語法。It uses the following syntax.

( OwnerPropertyArrayIndex ).( FreezablePropertyArrayIndex )( OwnerPropertyArrayIndex ).( FreezablePropertyArrayIndex )

WhereWhere

下列範例所示Path,伴隨PathParameters上述範例中所定義。The following example shows the Path that would accompany the PathParameters defined in the preceding example.

DependencyProperty[] propertyChain =
    new DependencyProperty[]
        {Rectangle.FillProperty, SolidColorBrush.ColorProperty};
string thePath = "(0).(1)";

下列範例會結合以動畫顯示先前範例中的程式碼ColorSolidColorBrush用以設定Fill矩形元素。The following example combines the code in the previous examples to animate the Color of a SolidColorBrush used to set the Fill of a rectangle element.


// Create a name scope for the page.
NameScope.SetNameScope(this, new NameScope()); 

Rectangle rectangle01 = new Rectangle();
rectangle01.Name = "Rectangle01";   
this.RegisterName(rectangle01.Name, rectangle01);
rectangle01.Width = 100;
rectangle01.Height = 100;
rectangle01.Fill = 
    (SolidColorBrush)this.Resources["MySolidColorBrushResource"];

ColorAnimation myColorAnimation = new ColorAnimation();
myColorAnimation.From = Colors.Blue;
myColorAnimation.To = Colors.AliceBlue;
myColorAnimation.Duration = new Duration(TimeSpan.FromSeconds(1));
Storyboard.SetTargetName(myColorAnimation, rectangle01.Name);

DependencyProperty[] propertyChain =
    new DependencyProperty[]
        {Rectangle.FillProperty, SolidColorBrush.ColorProperty};
string thePath = "(0).(1)";
PropertyPath myPropertyPath = new PropertyPath(thePath, propertyChain);
Storyboard.SetTargetProperty(myColorAnimation, myPropertyPath);

Storyboard myStoryboard = new Storyboard();
myStoryboard.Children.Add(myColorAnimation);
BeginStoryboard myBeginStoryboard = new BeginStoryboard();
myBeginStoryboard.Storyboard = myStoryboard;
EventTrigger myMouseEnterTrigger = new EventTrigger();
myMouseEnterTrigger.RoutedEvent = Rectangle.MouseEnterEvent;
myMouseEnterTrigger.Actions.Add(myBeginStoryboard);
rectangle01.Triggers.Add(myMouseEnterTrigger);

有時候您需要以集合或陣列中包含的 Freezable 為目標。Sometimes you need to target a freezable contained in a collection or array. 例如,假設矩形擁有TransformGroup資源套用至其RenderTransform屬性,而且您想要以動畫顯示它所包含的轉換的其中一個。For example, suppose that a rectangle has a TransformGroup resource applied to its RenderTransform property, and you want to animate one of the transforms it contains.

<TransformGroup x:Key="MyTransformGroupResource"
  x:Shared="False">
  <ScaleTransform />
  <RotateTransform />
</TransformGroup>  

目標Freezable包含在集合中,使用下列路徑語法。To target a Freezable contained in a collection, you use the following path syntax.

( OwnerPropertyArrayIndex ).( CollectionChildrenPropertyArrayIndex ) [ CollectionIndex ].( FreezablePropertyArrayIndex )( OwnerPropertyArrayIndex ).( CollectionChildrenPropertyArrayIndex ) [ CollectionIndex ].( FreezablePropertyArrayIndex )

何處CollectionIndex是其陣列或集合中物件的索引。Where CollectionIndex is the index of the object in its array or collection.

目標Angle的屬性RotateTransform中的第二個轉換TransformGroup,您可以使用下列PathPathParametersTo target the Angle property of the RotateTransform, the second transform in the TransformGroup, you would use the following Path and PathParameters.

DependencyProperty[] propertyChain =
    new DependencyProperty[]
        {
            Rectangle.RenderTransformProperty, 
            TransformGroup.ChildrenProperty,
            RotateTransform.AngleProperty
        };
string thePath = "(0).(1)[1].(2)";
PropertyPath myPropertyPath = new PropertyPath(thePath, propertyChain);
Storyboard.SetTargetProperty(myDoubleAnimation, myPropertyPath);

下列範例示範完整的程式碼建立動畫AngleRotateTransform內含TransformGroupThe following example shows the complete code for animating the Angle of a RotateTransform contained within a TransformGroup.

Rectangle rectangle02 = new Rectangle();
rectangle02.Name = "Rectangle02";
this.RegisterName(rectangle02.Name, rectangle02);
rectangle02.Width = 100;
rectangle02.Height = 100;
rectangle02.Fill = Brushes.Blue;
rectangle02.RenderTransform = 
    (TransformGroup)this.Resources["MyTransformGroupResource"];

DoubleAnimation myDoubleAnimation = new DoubleAnimation();
myDoubleAnimation.From = 0;
myDoubleAnimation.To = 360;
myDoubleAnimation.Duration = new Duration(TimeSpan.FromSeconds(1));
Storyboard.SetTargetName(myDoubleAnimation, rectangle02.Name);

DependencyProperty[] propertyChain =
    new DependencyProperty[]
        {
            Rectangle.RenderTransformProperty, 
            TransformGroup.ChildrenProperty,
            RotateTransform.AngleProperty
        };
string thePath = "(0).(1)[1].(2)";
PropertyPath myPropertyPath = new PropertyPath(thePath, propertyChain);
Storyboard.SetTargetProperty(myDoubleAnimation, myPropertyPath);

Storyboard myStoryboard = new Storyboard();
myStoryboard.Children.Add(myDoubleAnimation);
BeginStoryboard myBeginStoryboard = new BeginStoryboard();
myBeginStoryboard.Storyboard = myStoryboard;
EventTrigger myMouseEnterTrigger = new EventTrigger();
myMouseEnterTrigger.RoutedEvent = Rectangle.MouseEnterEvent;
myMouseEnterTrigger.Actions.Add(myBeginStoryboard);
rectangle02.Triggers.Add(myMouseEnterTrigger);

以 Freezable 作為起點的間接目標Indirectly Targeting with a Freezable as the Starting Point

先前各節說明如何設定間接目標Freezable開始FrameworkElement或是FrameworkContentElement並建立屬性鏈結連到Freezable子屬性。The previous sections described how to indirectly target a Freezable by starting with a FrameworkElement or FrameworkContentElement and creating a property chain to a Freezable sub-property. 您也可以使用Freezable做為開始點,並間接目標的其中一個其Freezable子屬性。You can also use a Freezable as a starting point and indirectly target one of its Freezable sub-properties. 在使用時,適用一個額外的限制Freezable做為起點的間接目標: 起始Freezable和每Freezable它與間接做為目標的子屬性之間都不能凍結。One additional restriction applies when using a Freezable as a starting point for indirect targeting: the starting Freezable and every Freezable between it and the indirectly targeted sub-property must not be frozen.

在 XAML 中以互動方式控制分鏡腳本Interactively Controlling a Storyboard in XAML

在中啟動分鏡腳本Extensible Application Markup Language (XAML)Extensible Application Markup Language (XAML),您使用BeginStoryboard觸發動作。To start a storyboard in Extensible Application Markup Language (XAML)Extensible Application Markup Language (XAML), you use a BeginStoryboard trigger action. BeginStoryboard 會將這些物件和屬性,它們建立動畫,並啟動分鏡腳本動畫。BeginStoryboard distributes the animations to the objects and properties they animate, and starts the storyboard. (如需此程序的詳細資訊,請參閱動畫和計時系統概觀。)如果您賦予BeginStoryboard藉由指定的名稱及其Name屬性,讓它可控制的分鏡腳本。(For details about this process, see the Animation and Timing System Overview.) If you give the BeginStoryboard a name by specifying its Name property, you make it a controllable storyboard. 接著在分鏡腳本啟動後,您就可能以互動方式控制它。You can then interactively control the storyboard after it's started. 以下是可控制之分鏡腳本動作的清單,您可以將這些動作與事件觸發程序搭配使用以控制分鏡腳本。The following is a list of controllable storyboard actions that you use with event triggers to control a storyboard.

在下列範例中,會使用可控制的分鏡腳本動作以互動方式控制分鏡腳本。In the following example, controllable storyboard actions are used to interactively control a storyboard.

<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  x:Class="Microsoft.SDK.Animation.ControllableStoryboardExample"
  WindowTitle="Fading Rectangle Example">
  <StackPanel Margin="10">

    <Rectangle
      Name="MyRectangle"
      Width="100" 
      Height="100"
      Fill="Blue">
    </Rectangle>

    <Button Name="BeginButton">Begin</Button>
    <Button Name="PauseButton">Pause</Button>
    <Button Name="ResumeButton">Resume</Button>
    <Button Name="SkipToFillButton">Skip To Fill</Button>
    <Button Name="StopButton">Stop</Button>

    <StackPanel.Triggers>
      <EventTrigger RoutedEvent="Button.Click" SourceName="BeginButton">
        <BeginStoryboard Name="MyBeginStoryboard">
          <Storyboard>
            <DoubleAnimation
              Storyboard.TargetName="MyRectangle" 
              Storyboard.TargetProperty="(Rectangle.Opacity)"
              From="1.0" To="0.0" Duration="0:0:5" />
          </Storyboard>
        </BeginStoryboard>
      </EventTrigger>
      <EventTrigger RoutedEvent="Button.Click" SourceName="PauseButton">
        <PauseStoryboard BeginStoryboardName="MyBeginStoryboard" />
      </EventTrigger>
      <EventTrigger RoutedEvent="Button.Click" SourceName="ResumeButton">
        <ResumeStoryboard BeginStoryboardName="MyBeginStoryboard" />
      </EventTrigger>
      <EventTrigger RoutedEvent="Button.Click" SourceName="SkipToFillButton">
        <SkipStoryboardToFill BeginStoryboardName="MyBeginStoryboard" />
      </EventTrigger>
      <EventTrigger RoutedEvent="Button.Click" SourceName="StopButton">
        <StopStoryboard BeginStoryboardName="MyBeginStoryboard" />
      </EventTrigger>
    </StackPanel.Triggers>
  </StackPanel>
</Page>

使用程式碼以互動方式控制分鏡腳本Interactively Controlling a Storyboard by Using Code

前述範例顯示如何使用觸發動作顯示動畫。The previous examples have shown how to animate using trigger actions. 程式碼中,您也可以控制使用互動方法分鏡腳本Storyboard類別。In code, you may also control a storyboard using interactive methods of the Storyboard class. 針對Storyboard設為互動式程式碼中,您必須使用分鏡腳本的適當多載Begin方法並指定true進行控制。For a Storyboard to be made interactive in code, you must use the appropriate overload of the storyboard's Begin method and specify true to make it controllable. 請參閱Begin(FrameworkElement, Boolean)頁面以取得詳細的資訊。See the Begin(FrameworkElement, Boolean) page for more information.

下列清單顯示可用來操作的方法Storyboard啟動之後:The following list shows the methods that can be used to manipulate a Storyboard after it has started:

使用這些方法的優點是,您不需要建立Trigger或是TriggerAction物件; 您只需要參考可控制Storyboard您想要操作。The advantage to using these methods is that you don't need to create Trigger or TriggerAction objects; you just need a reference to the controllable Storyboard you want to manipulate.

注意: 所執行的所有互動式動作Clock,因此也在Storyboard會在計時引擎就會發生下一次轉譯之前的下一個刻度上。Note: All interactive actions taken on a Clock, and therefore also on a Storyboard will occur on the next tick of the timing engine which will happen shortly before the next render. 例如,如果您使用Seek跳到另一個點的動畫,屬性值的方法不會立即變更,值而變更下一個刻度在計時引擎。For example, if you use the Seek method to jump to another point in an animation, the property value does not change instantly, rather, the value changes on the next tick of the timing engine.

下列範例示範如何套用和控制動畫的互動式方法Storyboard類別。The following example shows how to apply and control animations using the interactive methods of the Storyboard class.

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

namespace SDKSample
{

    public class ControllableStoryboardExample : Page
    {
        private Storyboard myStoryboard;

        public ControllableStoryboardExample()
        {

            // Create a name scope for the page.

            NameScope.SetNameScope(this, new NameScope()); 
 
            this.WindowTitle = "Controllable Storyboard Example";
            StackPanel myStackPanel = new StackPanel();
            myStackPanel.Margin = new Thickness(10);

            // Create a rectangle.
            Rectangle myRectangle = new Rectangle();
            myRectangle.Name = "myRectangle";

            // Assign the rectangle a name by 
            // registering it with the page, so that
            // it can be targeted by storyboard
            // animations.
            this.RegisterName(myRectangle.Name, myRectangle);
            myRectangle.Width = 100;
            myRectangle.Height = 100;
            myRectangle.Fill = Brushes.Blue;
            myStackPanel.Children.Add(myRectangle);

            //
            // Create an animation and a storyboard to animate the
            // rectangle.
            //
            DoubleAnimation myDoubleAnimation = new DoubleAnimation();
            myDoubleAnimation.From = 1.0;
            myDoubleAnimation.To = 0.0;
            myDoubleAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(5000));
            myDoubleAnimation.AutoReverse = true;

            // Create the storyboard.
            myStoryboard = new Storyboard();
            myStoryboard.Children.Add(myDoubleAnimation);
            Storyboard.SetTargetName(myDoubleAnimation, myRectangle.Name);
            Storyboard.SetTargetProperty(myDoubleAnimation, new PropertyPath(Rectangle.OpacityProperty));

            //
            // Create some buttons to control the storyboard
            // and a panel to contain them.
            //
            StackPanel buttonPanel = new StackPanel();
            buttonPanel.Orientation = Orientation.Horizontal;
            Button beginButton = new Button();
            beginButton.Content = "Begin";
            beginButton.Click += new RoutedEventHandler(beginButton_Clicked);
            buttonPanel.Children.Add(beginButton);
            Button pauseButton = new Button();
            pauseButton.Content = "Pause";
            pauseButton.Click += new RoutedEventHandler(pauseButton_Clicked);
            buttonPanel.Children.Add(pauseButton);
            Button resumeButton = new Button();
            resumeButton.Content = "Resume";
            resumeButton.Click += new RoutedEventHandler(resumeButton_Clicked);
            buttonPanel.Children.Add(resumeButton);
            Button skipToFillButton = new Button();
            skipToFillButton.Content = "Skip to Fill";
            skipToFillButton.Click += new RoutedEventHandler(skipToFillButton_Clicked);
            buttonPanel.Children.Add(skipToFillButton);
            Button setSpeedRatioButton = new Button();
            setSpeedRatioButton.Content = "Triple Speed";
            setSpeedRatioButton.Click += new RoutedEventHandler(setSpeedRatioButton_Clicked);
            buttonPanel.Children.Add(setSpeedRatioButton);
            Button stopButton = new Button();
            stopButton.Content = "Stop";
            stopButton.Click += new RoutedEventHandler(stopButton_Clicked);
            buttonPanel.Children.Add(stopButton);
            myStackPanel.Children.Add(buttonPanel);
            this.Content = myStackPanel;        
            

        }

        // Begins the storyboard.
        private void beginButton_Clicked(object sender, RoutedEventArgs args)
        {
            // Specifying "true" as the second Begin parameter
            // makes this storyboard controllable.
            myStoryboard.Begin(this, true);

        }

        // Pauses the storyboard.
        private void pauseButton_Clicked(object sender, RoutedEventArgs args)
        {
            myStoryboard.Pause(this);

        }

        // Resumes the storyboard.
        private void resumeButton_Clicked(object sender, RoutedEventArgs args)
        {
            myStoryboard.Resume(this);

        }

        // Advances the storyboard to its fill period.
        private void skipToFillButton_Clicked(object sender, RoutedEventArgs args)
        {
            myStoryboard.SkipToFill(this);

        }

        // Updates the storyboard's speed.
        private void setSpeedRatioButton_Clicked(object sender, RoutedEventArgs args)
        {
            // Makes the storyboard progress three times as fast as normal.
            myStoryboard.SetSpeedRatio(this, 3);

        }

        // Stops the storyboard.
        private void stopButton_Clicked(object sender, RoutedEventArgs args)
        {
            myStoryboard.Stop(this);

        }         

    }

}

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

Namespace SDKSample

    Public Class ControllableStoryboardExample
        Inherits Page
        Private myStoryboard As Storyboard

        Public Sub New()

            ' Create a name scope for the page.

            NameScope.SetNameScope(Me, New NameScope())

            Me.WindowTitle = "Controllable Storyboard Example"
            Dim myStackPanel As New StackPanel()
            myStackPanel.Margin = New Thickness(10)

            ' Create a rectangle.
            Dim myRectangle As New Rectangle()
            myRectangle.Name = "myRectangle"

            ' Assign the rectangle a name by 
            ' registering it with the page, so that
            ' it can be targeted by storyboard
            ' animations.
            Me.RegisterName(myRectangle.Name, myRectangle)
            myRectangle.Width = 100
            myRectangle.Height = 100
            myRectangle.Fill = Brushes.Blue
            myStackPanel.Children.Add(myRectangle)

            '
            ' Create an animation and a storyboard to animate the
            ' rectangle.
            '
            Dim myDoubleAnimation As New DoubleAnimation()
            myDoubleAnimation.From = 1.0
            myDoubleAnimation.To = 0.0
            myDoubleAnimation.Duration = New Duration(TimeSpan.FromMilliseconds(5000))
            myDoubleAnimation.AutoReverse = True

            ' Create the storyboard.
            myStoryboard = New Storyboard()
            myStoryboard.Children.Add(myDoubleAnimation)
            Storyboard.SetTargetName(myDoubleAnimation, myRectangle.Name)
            Storyboard.SetTargetProperty(myDoubleAnimation, New PropertyPath(Rectangle.OpacityProperty))

            '
            ' Create some buttons to control the storyboard
            ' and a panel to contain them.
            '
            Dim buttonPanel As New StackPanel()
            buttonPanel.Orientation = Orientation.Horizontal
            Dim beginButton As New Button()
            beginButton.Content = "Begin"
            AddHandler beginButton.Click, AddressOf beginButton_Clicked
            buttonPanel.Children.Add(beginButton)
            Dim pauseButton As New Button()
            pauseButton.Content = "Pause"
            AddHandler pauseButton.Click, AddressOf pauseButton_Clicked
            buttonPanel.Children.Add(pauseButton)
            Dim resumeButton As New Button()
            resumeButton.Content = "Resume"
            AddHandler resumeButton.Click, AddressOf resumeButton_Clicked
            buttonPanel.Children.Add(resumeButton)
            Dim skipToFillButton As New Button()
            skipToFillButton.Content = "Skip to Fill"
            AddHandler skipToFillButton.Click, AddressOf skipToFillButton_Clicked
            buttonPanel.Children.Add(skipToFillButton)
            Dim setSpeedRatioButton As New Button()
            setSpeedRatioButton.Content = "Triple Speed"
            AddHandler setSpeedRatioButton.Click, AddressOf setSpeedRatioButton_Clicked
            buttonPanel.Children.Add(setSpeedRatioButton)
            Dim stopButton As New Button()
            stopButton.Content = "Stop"
            AddHandler stopButton.Click, AddressOf stopButton_Clicked
            buttonPanel.Children.Add(stopButton)
            myStackPanel.Children.Add(buttonPanel)
            Me.Content = myStackPanel


        End Sub

        ' Begins the storyboard.
        Private Sub beginButton_Clicked(ByVal sender As Object, ByVal args As RoutedEventArgs)
            ' Specifying "true" as the second Begin parameter
            ' makes this storyboard controllable.
            myStoryboard.Begin(Me, True)

        End Sub

        ' Pauses the storyboard.
        Private Sub pauseButton_Clicked(ByVal sender As Object, ByVal args As RoutedEventArgs)
            myStoryboard.Pause(Me)

        End Sub

        ' Resumes the storyboard.
        Private Sub resumeButton_Clicked(ByVal sender As Object, ByVal args As RoutedEventArgs)
            myStoryboard.Resume(Me)

        End Sub

        ' Advances the storyboard to its fill period.
        Private Sub skipToFillButton_Clicked(ByVal sender As Object, ByVal args As RoutedEventArgs)
            myStoryboard.SkipToFill(Me)

        End Sub

        ' Updates the storyboard's speed.
        Private Sub setSpeedRatioButton_Clicked(ByVal sender As Object, ByVal args As RoutedEventArgs)
            ' Makes the storyboard progress three times as fast as normal.
            myStoryboard.SetSpeedRatio(Me, 3)

        End Sub

        ' Stops the storyboard.
        Private Sub stopButton_Clicked(ByVal sender As Object, ByVal args As RoutedEventArgs)
            myStoryboard.Stop(Me)

        End Sub

    End Class

End Namespace

在樣式中建立動畫Animate in a Style

您可以使用Storyboard物件來定義中的動畫StyleYou can use Storyboard objects to define animations in a Style. 使用建立動畫StoryboardStyle類似於使用Storyboard其他地方,使用下列三個例外狀況:Animating with a Storyboard in a Style is similar to using a Storyboard elsewhere, with the following three exceptions:

  • 您未指定TargetName;Storyboard永遠為目標的項目Style套用。You don't specify a TargetName; the Storyboard always targets the element to which the Style is applied. 目標Freezable物件,您必須使用間接目標。To target Freezable objects, you must use indirect targeting. 如需有關間接目標的詳細資訊,請參閱 < 間接目標一節。For more information about indirect targeting, see the Indirect Targeting section.

  • 您無法指定SourceNameforEventTriggerTriggerYou can't specify a SourceName for an EventTrigger or a Trigger.

  • 您無法使用動態資源參考或資料繫結運算式來設定Storyboard或動畫屬性值。You can't use dynamic resource references or data binding expressions to set Storyboard or animation property values. 這是因為所有東西放Style必須是安全執行緒,而且計時系統必須FreezeStoryboard物件,以使它們具備執行緒安全。That's because everything inside a Style must be thread-safe, and the timing system must FreezeStoryboard objects to make them thread-safe. AStoryboard如果它或它的子時間軸包含動態資源參考或資料繫結運算式不能凍結。A Storyboard cannot be frozen if it or its child timelines contain dynamic resource references or data binding expressions. 如需凍結和其他Freezable功能,請參閱Freezable 物件概觀For more information about freezing and other Freezable features, see the Freezable Objects Overview.

  • XAMLXAML,您不能宣告事件處理常式Storyboard或動畫事件。In XAMLXAML, you can't declare event handlers for Storyboard or animation events.

如需示範如何在樣式中定義分鏡腳本的範例,請參閱在樣式中的建立動畫範例。For an example showing how to define a storyboard in a style, see the Animate in a Style example.

在 ControlTemplate 中建立動畫Animate in a ControlTemplate

您可以使用Storyboard物件來定義中的動畫ControlTemplateYou can use Storyboard objects to define animations in a ControlTemplate. 使用建立動畫StoryboardControlTemplate類似於使用Storyboard其他地方,使用下列兩項例外狀況:Animating with a Storyboard in a ControlTemplate is similar to using a Storyboard elsewhere, with the following two exceptions:

如需範例,示範如何定義中的分鏡腳本ControlTemplate,請參閱 < 在 ControlTemplate 中的建立動畫範例。For an example showing how to define a storyboard in a ControlTemplate, see the Animate in a ControlTemplate example.

在屬性值變更時建立動畫Animate When a Property Value Changes

在樣式和控制項範本中,您可以使用 Trigger 物件在屬性變更時啟動分鏡腳本。In styles and control templates, you can use Trigger objects to start a storyboard when a property changes. 如需範例,請參閱動畫時在屬性值變更會觸發在 ControlTemplate 中的建立動畫For examples, see Trigger an Animation When a Property Value Changes and Animate in a ControlTemplate.

套用屬性的動畫Trigger物件的行為更複雜的方式比EventTrigger動畫開始使用Storyboard方法。Animations applied by property Trigger objects behave in a more complex fashion than EventTrigger animations or animations started using Storyboard methods. 這些 「 傳遞 」 與動畫定義其他Trigger物件,但以此撰寫EventTrigger和方法觸發動畫。They "handoff" with animations defined by other Trigger objects, but compose with EventTrigger and method-triggered animations.

另請參閱See also