2012-01-25 3 views
2

私はWinFormグ​​ラフィックスの知識を少しも得たいので、XNAの小さな2DエディタをWinForm Graphics-onlyに書き直しています。Winformで描画する

今、私は自分自身をタイルセットの新しいUserControlにしましたが、これまでのように、Paintメソッドはコントロールの初期化時にのみ呼び出されます。私はコントロールを永久にペイントしたいので(少なくともパフォーマンスを保存するために少なくともMouseOverイベントを介して)、Invalidate()メソッドがコントロールを再ペイントすると聞きましたが、ウェイもパフォーマンスが悪いと聞きました。

これらのパフォーマンス上の問題がなくても、私のUserControlペイント自体にコードを使用させる方法はありますか?

答えて

3

の方法は、ではありません。は、コントロールの初期化時にのみ呼び出されます。コントロールを再描画する必要があるたびに呼び出されます。これはもちろん、コントロールが初めて作成されたときに発生します。また、アプリケーションが最小化されてから復元されたとき、別のウィンドウがアプリケーション上を移動してその内容が隠されて削除されたときなどにも発生します。また、Invalidateメソッドまたは同等のメソッドを使用してコントロールのクライアント領域を無効にすると発生します。これはパフォーマンスの最適化としてWindowsの開発の初期段階で行われました。変更されていないものを再描画する必要はありません。

コントロールを強制的に再描画する場合は、Invalidate methodを呼び出して、再描画するクライアント領域の特定の領域を指定する必要があります。

ウェイは、あまりにも性能がありません」という言い方が分かりません。 Invalidateメソッドが遅くなることは不可能です。実行されるのは、アイドル状態(他のメッセージを処理していない状態)であればいつでも、ウィンドウを再描画する必要があることをWindowsに知らせるフラグが設定されます。

あなたはすぐあなたのコントロールを再描画するには、Windowsを強制する場合(それがアイドル状態であることを待たずに、初期の頃からのWindowsに組み込まれた別のパフォーマンスの最適化)、全て無効化の即時再描画を強制する、Update methodを呼び出します地域。

Paintイベントハンドラメソッド内で、の描画のコードが遅い場合は、遅くなる可能性があります。そして明らかに、最初にそれを見ずにコードを最適化する方法を教えてもらえません。


は、これらのパフォーマンスの問題がなくても、私のユーザーコントロールは、コードを経由して自分自身をペイントできるようにとにかくありますか?

Paintイベントは、コントロールがどのようにして自分自身をペイントすべきかを正確に示します。それがそこにある理由です。

あなたはPaintイベントではないペイントを行う場合は、あなたが描くものは先に述べたように、コントロールが再描画されていることを次の時間は(期待の任意の数に応じて起こると予想外のことができます消去されます発生)。

ただし、一時オブジェクトをコントロールのクライアント領域に塗りつぶすことがあります(MouseDownイベントに応答してドラッグ矩形を表示するなど)。その場合、Graphicsクラス(通常は、Paintイベントハンドラメソッドの引数として渡され、描画を行うメソッドを呼び出すメソッドのインスタンス)をいつでも取得できます。コントロールのCreateGraphics methodを呼び出すと、Graphicsオブジェクトが返されます。その後、Paintイベントハンドラメソッドの内部と同じように取得されたGraphicsオブジェクトに描画します。

明らかに(つまり、実際に犯人である場合)、これは/ Paintイベントハンドラメソッドの内部で任意のより高速な描画コード以下にする必要がありますすることはできませんが、それは、画面ではなく、すぐにを更新されますコントロールがアイドル状態で他のメッセージを処理していないときよりも

私は、このアプローチは、あなたが描くすべてがコントロールが再描画されることを次回に消去されますよう、のみ即座に提供すると一時的フィードバックを使用する必要があることを再び繰り返すだろう。その場合、Paintイベントが発生し、そのメソッドハンドラ内のコードが実行されます。これは、他の一回限りのイベントで何を描画したかについては何も分かりません。だからこそ、Paintイベントハンドラメソッド内ですべてが発生する必要があります。他のイベントによって再描画が必要になったときは、Invalidate(おそらく通常はUpdateではありません)を呼び出す必要があります。

+0

まずは、お返事いただきありがとうございます。まあ、それはパフォーマンスの問題ではないかもしれませんが、私のMouseMoveメソッドがコントロールが再描画されるのを待つ時間ですか?私はコントロールの中にScrollY-Variableを持っています。これはグラフィックスの位置を調整し、その側のvScrollbarによって調整されます。だから私はScrollY値を更新し、スクロールバーのInvalidateメソッドを呼び出すvScrollbar_Scrollイベントを持っています。しかしそれはちょうど非常に遅いです。私は間違って何をしていますか? –

+0

あなたのアドバイスのおかげで、私はもう少し研究し、問題を解決しました。私はControlStyles.AllPaintingInWmPaintとControlStyles.OptimizedDoubleBufferフラグをtrueに設定し、塗装面積を減らし、すべての作業を非常に円滑にしました。ありがとう! –

+1

@ハラルド:はい、はい。ダブルバッファリングは、UIアップデートをスムーズにするための標準的なアプローチです。通常、それはあなたが「遅い」と記述していたものではなく、ちらつきに応答して示されます。 'AllPaintingInWmPaint'は、' WM_ERASEBKGND'メッセージを処理し、デフォルトの色を塗りつぶすことによって、コントロールが最初に消去しないことを意味します。ダブルバッファリングはWinFormsによって提供されます。それはまずすべてをオフスクリーンバッファに描画し、オフスクリーンバッファをスクリーンに直接描画します。中間のペイントのすべてのステップが途中で発生することはないので、これは役立ちます。 –

関連する問題