このトピックでは、 Storyboard オブジェクトを使用してアニメーションを整理および適用する方法について説明します。 Storyboard オブジェクトを対話的に操作する方法と、間接的なプロパティターゲット構文について説明します。
[前提条件]
このトピックを理解するには、さまざまなアニメーションの種類とその基本的な機能について理解している必要があります。 アニメーションの概要については、「 アニメーションの概要」を参照してください。 添付プロパティの使用方法も把握しておく必要があります。 添付プロパティの詳細については、「添付プロパティの 概要」を参照してください。
ストーリーボードとは
アニメーションだけが便利な種類のタイムラインではありません。 タイムラインのセットを整理したり、プロパティにタイムラインを適用したりするために、その他のタイムライン クラスが用意されています。 コンテナータイムラインは、 TimelineGroup クラスから派生し、 ParallelTimeline と Storyboardが含まれます。
Storyboardは、コンテナー タイムラインの一種であり、含まれるタイムラインのターゲット情報を提供します。 ストーリーボードには、他のコンテナータイムラインやアニメーションなど、あらゆる種類の Timelineを含めることができます。 Storyboard オブジェクトを使用すると、さまざまなオブジェクトやプロパティに影響するタイムラインを 1 つのタイムライン ツリーに結合できるため、複雑なタイミング動作を簡単に整理および制御できます。 たとえば、これら 3 つの処理を行うボタンが必要であるとします。
ユーザーがボタンを選択すると、色が拡大および変更されます。
縮小してから、クリックすると元のサイズに戻ります。
無効になると縮小して、不透明度が50%に減少します。
この場合、同じオブジェクトに適用される複数のアニメーション セットがあり、ボタンの状態に応じて異なる時間に再生する必要があります。 Storyboard オブジェクトを使用すると、アニメーションを整理し、それらをグループ化して 1 つ以上のオブジェクトに適用できます。
ストーリーボードを使用できる場所
Storyboardを使用して、アニメーション化可能なクラスの依存関係プロパティをアニメーション化できます (クラスをアニメーション化する方法の詳細については、「アニメーションの概要」を参照してください)。 ただし、ストーリーボードはフレームワーク レベルの機能であるため、オブジェクトはNameScopeまたはFrameworkElementのFrameworkContentElementに属している必要があります。
たとえば、 Storyboard を使用して次の操作を行うことができます。
ボタンの背景 (SolidColorBrushの一種) を描画するFrameworkElement (フレームワーク以外の要素) をアニメーション化します。
SolidColorBrush (非フレームワーク要素) をアニメーション化して、GeometryDrawing (Image) を使用して表示されるFrameworkElement (非フレームワーク要素) の塗りを描画します。
コードで、SolidColorBrushがその名前をFrameworkElementに登録した場合に、SolidColorBrushを含むクラスで宣言されたFrameworkElementをアニメーション化します。
ただし、Storyboardを使用して、名前をSolidColorBrushまたはFrameworkElementに登録しなかった、またはFrameworkContentElementまたはFrameworkElementのプロパティを設定するために使用されなかったFrameworkContentElementをアニメーション化できませんでした。
ストーリーボードでアニメーションを適用する方法
Storyboardを使用してアニメーションを整理および適用するには、アニメーションをStoryboardの子タイムラインとして追加します。 Storyboard クラスは、Storyboard.TargetNameとStoryboard.TargetProperty添付プロパティを提供します。 アニメーションでこれらのプロパティを設定して、ターゲット オブジェクトとプロパティを指定します。
アニメーションをターゲットに適用するには、トリガー アクションまたはメソッドを使用して Storyboard を開始します。 XAML では、BeginStoryboard、EventTrigger、またはTriggerでDataTrigger オブジェクトを使用します。 コードでは、 Begin メソッドを使用することもできます。
次の表に、各 Storyboard の開始手法がサポートされているさまざまな場所 (インスタンスごと、スタイル、コントロール テンプレート、データ テンプレート) を示します。 "インスタンスごと" とは、スタイル、コントロール テンプレート、またはデータ テンプレートではなく、オブジェクトのインスタンスにアニメーションまたはストーリーボードを直接適用する手法を指します。
ストーリーボードの使用が開始されました... | インスタンスごと | 様式 | コントロール テンプレート | データ テンプレート | 例 |
---|---|---|---|---|---|
BeginStoryboard と EventTrigger | イエス | イエス | イエス | イエス | ストーリーボード を使用してプロパティをアニメーション化する |
BeginStoryboard およびプロパティ Trigger | いいえ | イエス | イエス | イエス | プロパティ値が変更されたときにアニメーションをトリガーする |
BeginStoryboard およびプロパティ MultiTrigger | いいえ | イエス | イエス | イエス | MultiTrigger クラスの例 |
BeginStoryboard と a DataTrigger | いいえ | イエス | イエス | イエス | 方法: データが変更されたときにアニメーションをトリガーする |
BeginStoryboard と a MultiDataTrigger | いいえ | イエス | イエス | イエス | MultiDataTrigger クラスの例 |
Begin メソッド | イエス | いいえ | いいえ | いいえ | ストーリーボード を使用してプロパティをアニメーション化する |
次の例では、Storyboardを使用して、Width要素のRectangleと、そのColorの描画に使用するSolidColorBrushの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;
}
}
}
次のセクションでは、添付プロパティの TargetName と TargetProperty について詳しく説明します。
ターゲット フレームワーク要素、フレームワーク コンテンツ要素、およびフリーザブル (Freezables)
前のセクションでは、アニメーションがターゲットを見つけるには、ターゲットの名前とアニメーション化するプロパティを認識する必要があることを説明しました。 アニメーション化するプロパティの指定は簡単です。アニメーション化するプロパティの名前 TargetProperty
設定するだけです。 アニメーション化するプロパティを持つオブジェクトの名前を指定するには、アニメーションの Storyboard.TargetName プロパティを設定します。
注意事項
Target
プロパティを使用して、TargetName
の代わりにオブジェクトに直接バインドすることはできますが、シリアル化することはできません。 XAML で Target
オブジェクトを正しく参照できる保証はありません。
TargetName プロパティを機能させるには、対象オブジェクトに名前が必要です。 XAML で名前を FrameworkElement または FrameworkContentElement に割り当てるのは、 Freezable オブジェクトに名前を割り当てるのとは異なります。
フレームワーク要素は、 FrameworkElement クラスから継承するクラスです。 フレームワーク要素の例としては、 Window、 DockPanel、 Button、 Rectangleなどがあります。 基本的に、すべてのウィンドウ、パネル、およびコントロールは要素です。 フレームワーク コンテンツ要素は、 FrameworkContentElement クラスから継承するクラスです。 フレームワーク コンテンツ要素の例としては、 FlowDocument や Paragraphなどがあります。 型がフレームワーク要素かフレームワーク コンテンツ要素かがわからない場合は、Name プロパティがあるかどうかを確認します。 その場合は、おそらくフレームワーク要素またはフレームワーク コンテンツ要素です。 確認するには、その型ページの [継承階層] セクションを確認してください。
XAML でフレームワーク要素またはフレームワーク コンテンツ要素のターゲット設定を有効にするには、その Name プロパティを設定します。 コードでは、 RegisterName メソッドを使用して、 NameScopeを作成した要素に要素の名前を登録する必要もあります。
前の例から取得した次の例では、種類がMyRectangle
であるRectangleを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);
名前が付いた後は、その要素のプロパティをアニメーション化できます。
<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の例としては、SolidColorBrush、RotateTransform、GradientStopなどがあります。
XAML でアニメーションによる Freezable のターゲット設定を有効にするには、 x:Name ディレクティブ を使用して名前を割り当てます。 コードでは、 RegisterName メソッドを使用して、 NameScopeを作成した要素にその名前を登録します。
次の例では、 Freezable オブジェクトに名前を割り当てます。
<SolidColorBrush x:Name="MySolidColorBrush" Color="Blue" />
SolidColorBrush mySolidColorBrush = new SolidColorBrush(Colors.Blue);
this.RegisterName("MySolidColorBrush", mySolidColorBrush);
その後、オブジェクトをアニメーションの対象にすることができます。
<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 プロパティを解決します。 WPF 名スコープの詳細については、「 WPF XAML 名前スコープ」を参照してください。 TargetNameプロパティを省略すると、アニメーションは定義されている要素を対象とします。スタイルの場合はスタイル付き要素を対象とします。
Freezable オブジェクトに名前を割り当てることができない場合があります。 たとえば、 Freezable がリソースとして宣言されている場合、またはスタイルのプロパティ値を設定するために使用される場合、名前を付けることはできません。 名前がないため、直接対象にすることはできませんが、間接的にターゲットにすることができます。 次のセクションでは、間接ターゲットを使用する方法について説明します。
間接ターゲット設定
Freezableがリソースとして宣言されている場合や、スタイルのプロパティ値を設定するために使用される場合など、Freezableをアニメーションで直接対象にできない場合があります。 このような場合、直接ターゲットにすることはできませんが、 Freezable オブジェクトをアニメーション化することはできます。 TargetNameの名前でFreezableプロパティを設定する代わりに、Freezableが属する要素の名前を指定します。たとえば、四角形要素のSolidColorBrushを設定するために使用されるFillは、その四角形に属します。 ブラシをアニメーション化するためには、TargetPropertyを使用して設定されたフレームワーク要素またはフレームワークコンテンツ要素のプロパティから始まり、Freezableとしてアニメーション化するプロパティで終わるプロパティチェーンを使ってアニメーションのFreezableを設定します。
<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が固定されている場合、複製が作成され、その複製がアニメーション化されることに注意してください。 この場合、元のオブジェクトの HasAnimatedProperties プロパティは、元のオブジェクトが実際にアニメーション化されていないため、 false
を返し続けます。 複製の詳細については、 Freezable オブジェクトの概要を参照してください。
また、間接プロパティ ターゲットを使用する場合は、存在しないオブジェクトをターゲットにすることもできます。 たとえば、特定のボタンの Background が SolidColorBrush で設定され、実際に LinearGradientBrush を使用してボタンの背景を設定したときに、その色をアニメーション化しようとしたとします。 このような場合、例外はスローされません。 LinearGradientBrush は Color プロパティの変更に反応しないため、アニメーションは表示効果を持つことができません。
次のセクションでは、間接プロパティのターゲット構文について詳しく説明します。
XAML で Freezable のプロパティを間接的にターゲットにする
XAML で freezable のプロパティをターゲットにするには、次の構文を使用します。
プロパティの構文 |
---|
ElementPropertyName. FreezablePropertyName |
どこ
ElementPropertyName は、FrameworkElementが設定に使用されるFreezableのプロパティです。
FreezablePropertyName は、アニメーション化する Freezable のプロパティです。
次のコードは、四角形要素のColorを設定するために使用されるSolidColorBrushのFillをアニメーション化する方法を示しています。
<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 をターゲットにする必要があります。
コレクションに含まれる freezable をターゲットにするには、次のパス構文を使用します。
パス構文 |
---|
ElementPropertyName.Children[ CollectionIndex]. FreezablePropertyName |
ここで CollectionIndex は、配列またはコレクション内のオブジェクトのインデックスです。
たとえば、四角形のTransformGroup プロパティにRenderTransform リソースが適用されていて、それに含まれる変換の 1 つをアニメーション化するとします。
<TransformGroup x:Key="MyTransformGroupResource"
x:Shared="False">
<ScaleTransform />
<RotateTransform />
</TransformGroup>
次のコードは、前の例で示したAngleのRotateTransform プロパティをアニメーション化する方法を示しています。
<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 のプロパティを間接的に対象とする
コードでは、 PropertyPath オブジェクトを作成します。 PropertyPathを作成するときは、PathとPathParametersを指定します。
PathParametersを作成するには、依存関係プロパティ識別子フィールドの一覧を含むDependencyProperty型の配列を作成します。 最初の識別子フィールドは、FrameworkElementを設定するために使用されるFrameworkContentElementまたはFreezableのプロパティ用です。 次の識別子フィールドは、ターゲットにする Freezable のプロパティを表します。 FreezableをFrameworkElement オブジェクトに接続するプロパティのチェーンと考えてください。
四角形要素のColorを設定するために使用されるSolidColorBrushのFillを対象とする依存関係プロパティ チェーンの例を次に示します。
DependencyProperty[] propertyChain =
new DependencyProperty[]
{Rectangle.FillProperty, SolidColorBrush.ColorProperty};
また、 Pathを指定する必要があります。 Pathは、Stringの解釈方法をPathに指示するPathParametersです。 次の構文を使用します。
プロパティ パスの構文 |
---|
(
OwnerPropertyArrayIndex).( FreezablePropertyArrayIndex) |
どこ
OwnerPropertyArrayIndex は、DependencyPropertyが設定に使用されるFrameworkElement オブジェクトのプロパティの識別子を含むFreezable配列のインデックスです。
FreezablePropertyArrayIndex は、ターゲットとなるプロパティの識別子を含む DependencyProperty 配列のインデックスです。
次の例は、前の例で定義したPathに付随するPathParametersを示しています。
DependencyProperty[] propertyChain =
new DependencyProperty[]
{Rectangle.FillProperty, SolidColorBrush.ColorProperty};
string thePath = "(0).(1)";
次の例では、前の例のコードを組み合わせて、四角形要素のColorを設定するために使用するSolidColorBrushのFillをアニメーション化します。
// 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 をターゲットにする必要があります。 たとえば、四角形のTransformGroup プロパティにRenderTransform リソースが適用されていて、それに含まれる変換の 1 つをアニメーション化するとします。
<TransformGroup x:Key="MyTransformGroupResource"
x:Shared="False">
<ScaleTransform />
<RotateTransform />
</TransformGroup>
コレクションに含まれる Freezable を対象にするには、次のパス構文を使用します。
パス構文 |
---|
(
OwnerPropertyArrayIndex).( CollectionChildrenPropertyArrayIndex) [ CollectionIndex].( FreezablePropertyArrayIndex) |
ここで CollectionIndex は、配列またはコレクション内のオブジェクトのインデックスです。
Angleの 2 番目の変換であるRotateTransformのTransformGroup プロパティをターゲットにするには、次のPathと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);
次の例は、Angleに含まれるRotateTransformの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 を使用して間接的にターゲットを設定する
前のセクションでは、FreezableまたはFrameworkElementから開始し、FrameworkContentElementサブプロパティへのプロパティ チェーンを作成して、Freezableを間接的にターゲットにする方法について説明しました。 Freezableを開始点として使用し、そのFreezableサブプロパティの 1 つを間接的にターゲットにすることもできます。 間接ターゲットの開始点として Freezable を使用する場合は、追加の制限が 1 つ適用されます。開始 Freezable と、その間のすべての Freezable と間接的に対象となるサブプロパティを固定することはできません。
XAML でストーリーボードを対話的に制御する
拡張可能なアプリケーション マークアップ言語 (XAML) でストーリーボードを開始するには、 BeginStoryboard トリガー アクションを使用します。 BeginStoryboard はアニメーションをアニメーション化するオブジェクトとプロパティに配布し、ストーリーボードを開始します。 (このプロセスの詳細については、「アニメーションとタイミング システムの概要」を参照してください)。BeginStoryboard プロパティを指定してNameに名前を付ける場合は、制御可能なストーリーボードにします。 その後、ストーリーボードの開始後に対話形式でストーリーボードを制御できます。 ストーリーボードを制御するためにイベント トリガーと共に使用する、制御可能なストーリーボード アクションの一覧を次に示します。
PauseStoryboard: ストーリーボードを一時停止します。
ResumeStoryboard: 一時停止したストーリーボードを再開します。
SetStoryboardSpeedRatio: ストーリーボードの速度を変更します。
SkipStoryboardToFill: ストーリーボードを、それがある場合に限り、その填充期間の終わりまで進めます。
StopStoryboard: ストーリーボードを停止します。
RemoveStoryboard: ストーリーボードを削除します。
次の例では、制御可能なストーリーボード アクションを使用してストーリーボードを対話形式で制御します。
<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>
コードを使用してストーリーボードを対話的に制御する
前の例では、トリガー アクションを使用してアニメーション化する方法を示しました。 コードでは、 Storyboard クラスの対話型メソッドを使用してストーリーボードを制御することもできます。 コードで Storyboard を対話形式にするには、ストーリーボードの Begin メソッドの適切なオーバーロードを使用し、 true
を指定して制御できるようにする必要があります。 詳細については、 Begin(FrameworkElement, Boolean) ページを参照してください。
次の一覧は、開始後に Storyboard を操作するために使用できるメソッドを示しています。
これらのメソッドを使用する利点は、 Trigger オブジェクトや TriggerAction オブジェクトを作成する必要がないということです。操作する制御可能な Storyboard への参照が必要です。
注
Clockの対話型アクション、およびStoryboardの対話型アクションは、次のレンダリング直前に行われるタイミングエンジンの次のサイクルで実行されます。 たとえば、 Seek メソッドを使用してアニメーション内の別のポイントにジャンプする場合、プロパティの値はすぐには変化せず、タイミング エンジンの次のティックで値が変化します。
次の例は、 Storyboard クラスの対話型メソッドを使用してアニメーションを適用および制御する方法を示しています。
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 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
特定のスタイルでアニメーションする
Storyboardオブジェクトを使用して、Styleでアニメーションを定義できます。 StoryboardでStyleを使用してアニメーション化することは、他の場所でStoryboardを使用するのと似ていますが、次の 3 つの例外があります。
TargetNameは指定しません。Storyboardは常に、Styleが適用される要素を対象とします。 Freezableオブジェクトをターゲットにするには、間接ターゲット設定を使用する必要があります。 間接ターゲットの詳細については、「間接ターゲット設定」セクション を 参照してください。
SourceNameまたはEventTriggerのTriggerを指定することはできません。
動的リソース参照またはデータ バインディング式を使用して、 Storyboard またはアニメーション のプロパティ値を設定することはできません。 これは、 Style 内のすべてのものがスレッド セーフである必要があり、タイミング システムがオブジェクトをスレッド セーフにするために FreezeStoryboard する必要があるためです。 Storyboardまたはその子タイムラインに動的リソース参照またはデータ バインディング式が含まれている場合は、固定できません。 フリーズやその他の Freezable 機能の詳細については、「 Freezable オブジェクトの概要」を参照してください。
XAML では、 Storyboard イベントまたはアニメーション イベントのイベント ハンドラーを宣言することはできません。
スタイルでストーリーボードを定義する方法を示す例については、「 スタイルのアニメーション化 」の例を参照してください。
ControlTemplate でアニメーション化する
Storyboardオブジェクトを使用して、ControlTemplateでアニメーションを定義できます。 StoryboardでControlTemplateを使用してアニメーション化することは、他の場所でStoryboardを使用するのと似ていますが、次の 2 つの例外があります。
TargetNameは、ControlTemplateの子オブジェクトのみを参照できます。 TargetNameが指定されていない場合、アニメーションはControlTemplateが適用される要素を対象とします。
SourceNameまたはEventTriggerのTriggerは、ControlTemplateの子オブジェクトのみを参照できます。
動的リソース参照またはデータ バインディング式を使用して、 Storyboard またはアニメーション のプロパティ値を設定することはできません。 これは、 ControlTemplate 内のすべてのものがスレッド セーフである必要があり、タイミング システムがオブジェクトをスレッド セーフにするために FreezeStoryboard する必要があるためです。 Storyboardまたはその子タイムラインに動的リソース参照またはデータ バインディング式が含まれている場合は、固定できません。 フリーズやその他の Freezable 機能の詳細については、「 Freezable オブジェクトの概要」を参照してください。
XAML では、 Storyboard イベントまたはアニメーション イベントのイベント ハンドラーを宣言することはできません。
ControlTemplateでストーリーボードを定義する方法を示す例については、ControlTemplate のアニメーション化の例を参照してください。
プロパティ値が変更されたときにアニメーション化する
スタイルとコントロール テンプレートでは、Trigger オブジェクトを使用して、プロパティが変更されたときにストーリーボードを開始できます。 例については、「プロパティ値が変更されたときにアニメーションをトリガーする」および「ControlTemplateでアニメーションする」を参照してください。
プロパティ Trigger オブジェクトによって適用されるアニメーションは、EventTrigger アニメーションや Storyboard メソッドを使用して開始されるアニメーションよりも、より複雑な方法で動作します。 それらは、他の Trigger オブジェクトによって定義されているアニメーションとは "ハンドオフ" しますが、EventTrigger およびメソッドでトリガーされたアニメーションとは複合 (compose) します。
こちらも参照ください
.NET Desktop feedback