投稿者 魔界の仮面弁士  (社会人) 投稿日時 2011/10/9 19:32:05
以下、描画処理のルールとして:

・CreateGraphics は基本的に使わないようにします。たとえば、フォームの DoubleBuffered プロパティを使う場合、Paint イベントならその恩恵を受けられますが、CreateGraphics に対しては無効です。CreateGraphics が必要となるのは、描画タイミングを自分で制御しなければならない場合や、独自のバッファリング処理が必要なケースなどといった特殊なケースのみです。

・(アナログ時計の文字盤などのように)変化の少ない画像は、Bitmap を用意して、それを PictureBox の BackgroundImage もしくは Image プロパティとして割り当てるようにすると良いでしょう。

・Bitmap の内容を動的に作成したい場合は、Graphics.FromImage 経由で描画することができます。

・それ以外の描画処理は、基本的に描画系イベントで行うことになります。たとえば PictureBox なら Paint イベント、DataGridView なら RowPrePaint/RowPostPaint/CellPainting イベントが使えます。

・描画系イベントは、システム側から「再描画が必要とされるタイミング」で呼び出され、その描画に必要な Graphics オブジェクトも引数として渡される仕組みになっています。たとえば、DataGridView ならデータがスクロールされて新たなセルが描画されるタイミング、Form なら上に重なっていたウィンドウが取り除かれた場合などに呼び出され、引数 e.Graphics から Graphics オブジェクトを得られます。

・アナログ時計の針を描画する場合などのように、データ更新のタイミングで描画内容を更新したい場合には、描画依頼系のメソッドを呼び出します。具体的には、PictureBox の Invalidate メソッド、DataGridView の InvalidateCell、InvalidateRow、InvalidateColumn メソッドなどです。

・Invalidate 系メソッドは、コントロールに描画を依頼しますが、実際に再描画されるのはアイドル時(他の処理が実行されていないタイミング等)に限られます。ループ処理の最中に連続して最描画したいような場合には、強制描画のために Update もしくは Refresh メソッドを呼び出すことになります。Invalidate / Update / Reresh の違いについては下記を参照してみてください。
http://dobon.net/vb/dotnet/control/refreshupdateinvalidate.html

・CreateGraphics や Graphics.FromImage で生成した Graphics オブジェクトは、使用後に必ず 「Dispose メソッド」を呼んで破棄する必要があります(VB2005 以降では、Using ブロックを使うのが好ましいです)。そのほか、Image(Bitmap等)、Font、Pen、Brush 等も Dispose が必要なオブジェクトです。

・一方、Paint イベントで得られた e.Graphics は Dispose してはいけません。これは自分で生成したオブジェクトではなく、システム側から渡されたオブジェクトであるためです。

・Dispose は破棄命令なので、他のコントロール等で利用中のオブジェクト(Image や Font 等)を Dispose しないように注意しましょう。

・Pen や SolidBrush を New した場合には、(自分で生成したものなので)使用後に Dispose する責任がありますが、Brushes クラスや Pens クラスの Shared メンバーで得られるオブジェクトなどは、(自分で生成したものではないため)Dispose してはいけません。