3

ペイント イベントを介して描画される 3 つのデータ グラフがあります。グラフに挿入する必要があるデータがある場合、コントロールの invalidate() コマンドを呼び出します。

最初のコントロールのペイント イベントは、他の 2 つのグラフのビットマップ バッファを実際に作成し、長いループの繰り返しを回避します。

したがって、無効化コマンドは特定の順序 (1、2、3) になっています。これはうまく機能しますが、グラフ化されたデータが通常はスクロールを開始するグラフ ウィンドウ (PictureBox) の最後に到達すると、ペイント イベントが間違った順序 (2、3、1) で発生し始めます。

誰もこれに遭遇したことがありますか?なぜこれが起こっているのでしょうか?

4

2 に答える 2

5

コードを変更してInvalidate、3 つのコントロールのいずれかを呼び出す前に、1 つの共有ビットマップ バッファーを (おそらくコントロール クラスの静的メンバーとして) 作成してから、各コントロール呼び出すようInvalidateにします。コントロールのPaintイベント内で静的ビットマップ バッファを使用でき、Paintイベントが発生する順序は問題になりません。

コントロールを呼び出すときInvalidateは、基本的に、そのコントロールに WM_PAINT メッセージを送信するよう OS に指示していることになります。これは Windows メッセージであるため、Windows が処理を開始するたびに配信されることが保証されています。あなたの場合、通常は受け取った順序で配送されますが、そうでない場合もあります。

コードで考慮すべきもう 1 つの点: コントロールのPaintイベント ハンドラー内 (またはイベント ハンドラーから直接呼び出されるメソッド内) に比較的複雑な描画コードを配置すると、何らかの理由Paintでコントロールが無効になるたびにこのコードが実行されます。つまり、コードは を呼び出したときに実行されますが、別のウィンドウがコントロール上にドラッグされるたびにも実行されます。Invalidate

複雑で時間のかかるグラフィックスの場合、隠しバッファ (Bitmapまたは不可視PictureBoxなど) で複雑なレンダリングを実行し、コントロールのPaintイベントで隠しバッファから可視ウィンドウに単純なコピーを実行するのが常に最善です (Graphics.DrawImageまたはBitBltまたは何でも)。

このアプローチでは、描画するバッファーと表示されているウィンドウの間に 2 つ目のバッファーを追加すると、ちらつきを回避することもできます (したがって、「ダブル バッファーリング」)。メイン バッファーでの描画が完了したら、それを 2 番目のバッファーにコピーします。コントロールのPaintイベントでは、2 番目のバッファーから表示されているウィンドウにコピーします。

于 2010-04-10T22:14:48.103 に答える
3

コントロールの呼び出しInvalidate()は、基本的にオペレーティング システムにコントロールの再描画をスケジュールするように要求するため、これが特定の順序で行われるという保証はありません。

特定の順序で呼び出そうとしてInvalidate()いるので、これを行う単一のメソッドがあると思います。これらの呼び出しの直前にコードを追加して、無効化されたコントロールによって使用されるビットマップ バッファーを描画できます。これが発生するかどうかはわかりませんが、これにより、データが変更されていない場合にコントロールを無効にしないという自由も得られます。さらに、コントロールはいつでも無効にすることができます。たとえば、コントロール 1 を越えてフォームを移動すると、フォームが無効になり、現在のセットアップでは、必要ないときにバッファー ビットマップを再計算します。したがって、この機能を分離する必要があります。

于 2010-04-10T22:51:59.963 に答える