コードを変更して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 番目のバッファーから表示されているウィンドウにコピーします。