WPF アニメーション エンジンには、フレーム ベースのアニメーションを作成するための多くの機能が用意されています。 ただし、フレームごとにレンダリングをきめ細かく制御する必要があるアプリケーション シナリオがあります。 CompositionTarget オブジェクトは、フレームごとのコールバックに基づいてカスタム アニメーションを作成する機能を提供します。
CompositionTarget は、アプリケーションが描画されている表示サーフェイスを表す静的クラスです。 Rendering イベントは、アプリケーションのシーンが描画されるたびに発生します。 レンダリング フレーム レートは、シーンが 1 秒あたりに描画される回数です。
手記
CompositionTargetを使用した完全なコード サンプルについては、「Using the CompositionTarget Sample」を参照してください。
例
Rendering イベントは、WPF レンダリング プロセス中に発生します。 次の例は、CompositionTargetの静的 Rendering メソッドに EventHandler デリゲートを登録する方法を示しています。
// Add an event handler to update canvas background color just before it is rendered.
CompositionTarget.Rendering += UpdateColor;
' Add an event handler to update canvas background color just before it is rendered.
AddHandler CompositionTarget.Rendering, AddressOf UpdateColor
レンダリング イベント ハンドラー メソッドを使用して、カスタム描画コンテンツを作成できます。 このイベント ハンドラー メソッドは、フレームごとに 1 回呼び出されます。 WPF がビジュアル ツリー内の永続化されたレンダリング データをコンポジション シーン グラフにマーシャリングするたびに、イベント ハンドラー メソッドが呼び出されます。 さらに、ビジュアル ツリーに対する変更によってコンポジション シーン グラフが強制的に更新されると、イベント ハンドラー メソッドも呼び出されます。 イベント ハンドラー メソッドは、レイアウトの計算後に呼び出されることに注意してください。 ただし、イベント ハンドラー メソッドではレイアウトを変更できます。つまり、レイアウトはレンダリングの前にもう一度計算されます。
次の例は、CompositionTarget イベント ハンドラー メソッドでカスタム描画を提供する方法を示しています。 この場合、Canvas の背景色は、マウスの座標位置に基づいて色の値で描画されます。 Canvas内でマウスを動かすと、背景色が変わります。 さらに、現在の経過時間とレンダリングされたフレームの合計数に基づいて、平均フレーム レートが計算されます。
// Called just before frame is rendered to allow custom drawing.
protected void UpdateColor(object sender, EventArgs e)
{
if (_frameCounter++ == 0)
{
// Starting timing.
_stopwatch.Start();
}
// Determine frame rate in fps (frames per second).
long frameRate = (long)(_frameCounter / this._stopwatch.Elapsed.TotalSeconds);
if (frameRate > 0)
{
// Update elapsed time, number of frames, and frame rate.
myStopwatchLabel.Content = _stopwatch.Elapsed.ToString();
myFrameCounterLabel.Content = _frameCounter.ToString();
myFrameRateLabel.Content = frameRate.ToString();
}
// Update the background of the canvas by converting MouseMove info to RGB info.
byte redColor = (byte)(_pt.X / 3.0);
byte blueColor = (byte)(_pt.Y / 2.0);
myCanvas.Background = new SolidColorBrush(Color.FromRgb(redColor, 0x0, blueColor));
}
' Called just before frame is rendered to allow custom drawing.
Protected Sub UpdateColor(ByVal sender As Object, ByVal e As EventArgs)
If _frameCounter = 0 Then
' Starting timing.
_stopwatch.Start()
End If
_frameCounter = _frameCounter + 1
' Determine frame rate in fps (frames per second).
Dim frameRate As Long = CLng(Fix(_frameCounter / Me._stopwatch.Elapsed.TotalSeconds))
If frameRate > 0 Then
' Update elapsed time, number of frames, and frame rate.
myStopwatchLabel.Content = _stopwatch.Elapsed.ToString()
myFrameCounterLabel.Content = _frameCounter.ToString()
myFrameRateLabel.Content = frameRate.ToString()
End If
' Update the background of the canvas by converting MouseMove info to RGB info.
Dim redColor As Byte = CByte(_pt.X / 3.0)
Dim blueColor As Byte = CByte(_pt.Y / 2.0)
myCanvas.Background = New SolidColorBrush(Color.FromRgb(redColor, &H0, blueColor))
End Sub
カスタム図面は、異なるコンピューター上で異なる速度で実行されている場合があります。 これは、カスタム図面がフレーム レートに依存しないためです。 実行しているシステムとそのシステムのワークロードによっては、Rendering イベントは 1 秒あたりに異なる回数呼び出される場合があります。 WPF アプリケーションを実行するデバイスのグラフィックス ハードウェアの機能とパフォーマンスの決定については、「Graphics Rendering Tiers」を参照してください。
イベントの発生中にレンダリング EventHandler デリゲートを追加または削除すると、イベントの発生が完了するまで遅延します。 これは、共通言語ランタイム (CLR) での MulticastDelegateベースのイベントの処理方法と一致します。 また、レンダリング イベントが特定の順序で呼び出されるとは限りません。 特定の順序に依存する複数の EventHandler デリゲートがある場合は、1 つの Rendering イベントを登録し、デリゲートを正しい順序で多重化する必要があります。
関連項目
.NET Desktop feedback