How to: Render on a Per Frame Interval Using CompositionTarget
WPFのアニメーション・エンジンは、フレームベースのアニメーションを作成するための多くの機能を提供します。しかしながら、フレームごとのレンダリングをよりきめ細かく制御する必要があるアプリケーションのシナリオがあります。CompositionTargetオブジェクトは、フレームごとのコールバックに基づいて、カスタム・アニメーションを作成する能力を提供します。
CompositionTargetは、アプリケーションが描画されている表示面を表すstaticクラスです。アプリケーションのシーンが描画されるたびに、Renderingイベントが、発生します。レンダリング・フレーム・レートは、シーンが1秒間に描画される回数です。
CompositionTargetを使用した完全なコード・サンプルについては、「CompositionTargetサンプルの使用」を参照してください。
例
Example
Renderingイベントは、WPFのレンダリング・プロセスの間に発生します。次の例は、EventHandlerデリゲートをCompositionTargetの静的Renderingメソッドに、どのように、登録するかを示しています。
// Add an event handler to update canvas background color just before it is rendered.
// イベント・ハンドラを追加して、レンダリングされる直前にキャンバスの背景色を更新します。
CompositionTarget.Rendering += UpdateColor;
あなたは、カスタム描画コンテンツを作成するために、あなたのレンダリング・イベント・ハンドラ・メソッドを使用することができます。このイベント・ハンドラ・メソッドは、フレームにごとに、一度呼び出されます。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).
// fps(フレーム/秒)で、フレーム・レートを決定します。
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.
// MouseMove情報をRGB情報に変換することで、キャンバスの背景を更新します。
byte redColor = (byte)(_pt.X / 3.0);
byte blueColor = (byte)(_pt.Y / 2.0);
myCanvas.Background = new SolidColorBrush(Color.FromRgb(redColor, 0x0, blueColor));
}
あなたは、カスタム描画が、さまざまなコンピューターで、さまざまな速度で、実行されることに気付くかもしれません。これは、あなたのカスタム描画が、独立したフレーム・レートではないからです。あなたが実行しているシステムとそのシステムの作業負担に応じて、Renderingイベントは、1秒間に、異なる回数呼び出される場合があります。WPFアプリケーションを実行するデバイスのグラフィック・ハードウェアの機能と性能を判別する情報については、「グラフィック・レンダリング層」を参照してください。
イベントの発生中にレンダリングEventHandlerデリゲートを追加、あるいは、削除すると、イベントの発生が終了するまで遅延します。これは、MulticastDelegateに基づいたイベントが、共通言語ランタイム(CLR)で、どのように、処理されるかと一致しています。レンダリング・イベントが、特定の順序で呼び出されるとは限らないことにも注意してください。あなたが、特定の順序に依存する複数のEventHandlerデリゲートを持っている場合、あなたは、一つのRenderingイベントを登録し、デリゲートを正しい順序で、自分で多重化する必要があります。