タイミング イベントの概要

このトピックでは、Timeline および Clock オブジェクトで使用できる 5 つのタイミング イベントの使用方法について説明します。

必須コンポーネント

このトピックを理解するには、アニメーションの作成方法と使用方法について理解している必要があります。 アニメーションの概要については、「アニメーションの概要」をご覧ください。

WPF でプロパティをアニメーション化するには、複数の方法があります。

マークアップとコードで使用できるという理由から、この概要の例では Storyboard オブジェクトを使用しています。 ただし、説明されている概念は、プロパティをアニメーション化するためのその他の方法にも適用できます。

クロックとは

タイムラインは、時間のセグメントについて説明する以外は、それ自身が実際に何かを行うものではありません。 実際の処理を行うのは、タイムラインの Clock オブジェクトです。このオブジェクトは、タイムラインのタイミングに関連する実行時状態を維持します。 多くの場合(ストーリー ボードを使用する場合など)には、タイムラインに対してクロックが自動的に作成されます。 また、CreateClock メソッドを使用して Clock を明示的に作成することもできます。 Clock オブジェクトについて詳しくは、「アニメーションとタイミング システムの概要」をご覧ください。

イベントを使用する理由

1 つの例外 (最後のティックに配置されたシーク) を除いて、すべての対話型タイミング操作は非同期です。 これらがいつ実行されるかを正確に知る方法はありません。 これは、タイミング操作に依存する他のコードが存在する場合に、問題となることがあります。 たとえば、四角形をアニメーション化するタイムラインを停止する必要があるとします。 そしてタイムラインを停止した後に、四角形の色を変更するとします。

myStoryboard.Stop(myRectangle);

// This statement might execute
// before the storyboard has stopped.
myRectangle.Fill = Brushes.Blue;
myStoryboard.Stop(myRectangle)

' This statement might execute
' before the storyboard has stopped.
myRectangle.Fill = Brushes.Blue

上記の例では、ストーリー ボードが停止する前に、2 行目のコードが実行される可能性があります。 これは、停止が非同期の操作であるためです。 タイムラインやクロックに停止を指示すると、タイミング エンジンの次のティックまで処理されない「停止要求」が作成されます。

タイムラインの完了後にコマンドを実行するには、タイミング イベントを使用します。 次の例では、ストーリー ボードが停止した後に四角形の色が変更されるよう、イベント ハンドラーが使用されています。

// Register for the CurrentStateInvalidated timing event.
myStoryboard.CurrentStateInvalidated += new EventHandler(myStoryboard_CurrentStateInvalidated);
' Register for the CurrentStateInvalidated timing event.
AddHandler myStoryboard.CurrentStateInvalidated, AddressOf myStoryboard_CurrentStateInvalidated
// Change the rectangle's color after the storyboard stops.
void myStoryboard_CurrentStateInvalidated(object sender, EventArgs e)
{
    Clock myStoryboardClock = (Clock)sender;
    if (myStoryboardClock.CurrentState == ClockState.Stopped)
    {
        myRectangle.Fill = Brushes.Blue;
    }
}
' Change the rectangle's color after the storyboard stops. 
Private Sub myStoryboard_CurrentStateInvalidated(ByVal sender As Object, ByVal e As EventArgs)
    Dim myStoryboardClock As Clock = CType(sender, Clock)
    If myStoryboardClock.CurrentState = ClockState.Stopped Then
        myRectangle.Fill = Brushes.Blue
    End If
End Sub

より詳しい例については、「クロックの状態が変化したときに通知を受け取る」をご覧ください。

パブリック イベント

Timeline および Clock クラスでは、5 つのタイミング イベントが提供されます。 次の表は、これらのイベントと、それらをトリガーする条件を示したものです。

event 対話型操作のトリガー その他のトリガー
Completed 塗りつぶしまでスキップ 時計が完了する。
CurrentGlobalSpeedInvalidated 一時停止、再開、シーク、速度比を設定、塗りつぶしまでスキップ、停止 クロックが反転、加速、開始、または停止する。
CurrentStateInvalidated 開始、塗りつぶしまでスキップ、停止 クロックが開始、停止、または塗りつぶされる。
CurrentTimeInvalidated 開始、シーク、塗りつぶしまでスキップ、停止 クロックが進行する。
RemoveRequested 削除

ティッキングとイベントの統合

WPF でオブジェクトをアニメーション化する際、アニメーションを管理するのはタイミング エンジンです。 タイミング エンジンは、時間の進行状況を追跡し、それぞれのアニメーションの状態を計算します。 これにより、多数の評価パスが瞬時に作成されます。 これらの評価パスは「ティック」と呼ばれます。

ティックは頻繁に発生しますが、各ティックの間には多くのことが起こる可能性があります。 たとえば、タイムラインが停止され、開始され、再度停止された場合、その現行状態は 3 回変更されることになります。 理論上、イベントは 1 つのティックで複数回発生することができますが、タイミング エンジンではイベントが統合されるため、各イベントの発生回数はティックあたり最大で 1回となります。

イベントの登録

タイミング イベントを登録する方法は 2 つあります。 タイムラインに登録する方法と、タイムラインから作成されたクロックに登録する方法です。 クロックに直接登録する方法は非常に分かりやすいですが、これはコードからのみ実行できます。 タイムラインに登録する場合は、マークアップまたはコードからイベントを登録できます。 次のセクションでは、クロック イベントをタイムラインに登録する方法について説明します。

クロック イベントをタイムラインに登録する

タイムラインの CompletedCurrentGlobalSpeedInvalidatedCurrentStateInvalidatedCurrentTimeInvalidated、および RemoveRequested イベントは、タイムラインに関連付けられているように見えますが、これらのイベントを登録した場合、実際には、タイムラインに対して作成された Clock に、イベント ハンドラーが関連付けられます。

たとえば、Completed イベントをタイムラインに登録した場合、実際には、タイムラインに対して作成された各クロックの Completed イベントを登録するようシステムに指示したことになります。 コードでは、そのタイムラインに対して Clock が作成される前に、このイベントを登録する必要があります。そうしないと、通知を受信できません。 これは、XAML では自動的に処理されます。Clock が作成される前に、パーサーによって自動的にイベントが登録されます。

関連項目