WPF アニメーション エンジンには、フレーム ベースのアニメーションを作成するための多くの機能が用意されています。 ただし、フレームごとにレンダリングをきめ細かく制御する必要があるアプリケーション シナリオがあります。 CompositionTarget オブジェクトは、フレームごとのコールバックに基づいてカスタム アニメーションを作成する機能を提供します。
CompositionTarget は、アプリケーションが描画されている表示サーフェイスを表す静的クラスです。 Rendering イベントは、アプリケーションのシーンが描画されるたびに発生します。 レンダリング フレーム レートは、シーンが 1 秒あたりに描画される回数です。
注
CompositionTargetを使用した完全なコード サンプルについては、「CompositionTarget サンプルの使用」を参照してください。
例
Rendering イベントは、WPF レンダリング プロセス中に発生します。 次の例は、EventHandlerの静的Rendering メソッドにCompositionTarget デリゲートを登録する方法を示しています。
// 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 アプリケーションを実行するデバイスのグラフィックス ハードウェア機能とパフォーマンスの決定については、「 グラフィックス レンダリング層」を参照してください。
イベントの発生中にレンダリング EventHandler デリゲートを追加または削除すると、イベントの発生が完了するまで遅延します。 これは、共通言語ランタイム (CLR) での MulticastDelegateベースのイベントの処理方法と一致します。 また、レンダリング イベントが特定の順序で呼び出されるとは限りません。 特定の順序に依存する複数の EventHandler デリゲートがある場合は、1 つの Rendering イベントを登録し、デリゲートを正しい順序で多重化する必要があります。
こちらも参照ください
.NET Desktop feedback