.NET TIPS ウィンドウのリサイズ時に再描画を行うには?デジタルアドバンテージ2004/07/30 |
|
|
ウィンドウに(フォーム上に)グラフィックの描画を行う場合には、当然ながらウィンドウのリサイズ時にも正しく再描画されるようにしなくてはならない。本稿ではウィンドウのリサイズ時の再描画方法について解説する。
OnPaintメソッドによるグラフィックの描画
ウィンドウへの描画は、Formクラス(System.Windows.Forms名前空間)のOnPaintメソッドをオーバーライドするか、Paintイベントのイベント・ハンドラを追加して行うのが基本的なやり方だ(正確には、OnPaintメソッドはFormクラスのスーパー・クラスであるControlクラス(System.Windows.Forms名前空間)から継承したメソッド)。
次のサンプル・コード*は、オーバーライドしたOnPaintメソッドにおいて、クライアント領域全体にビットマップを表示するものだ。表示用のビットマップは、フォームのロード時にWebサイトから取得している(これについては「TIPS:画像を読み込むには?」の「Web上の画像の読み込み」で解説している)。
* このサンプル・コードを試すには、まずVisual Studio .NETで新しいプロジェクトとして「Windows アプリケーション」を選択してプロジェクトを作成する。そしてフォームをダブルクリックしてコードを開き、自動作成されているForm1_Loadメソッドを削除してから、このサンプル・コードをコピー&ペーストすればよい。 |
|
|
OnPaintメソッドによりビットマップを表示するC#のコード(一部) |
|
|
OnPaintメソッドによりビットマップを表示するVB.NETのコード(一部) |
OnPaintメソッドでは、フォームのClientRectangleプロパティにより、クライアント領域の表す四角形(左上隅の座標とクライアント領域の幅および高さを含んでいる)を得て、それと同じサイズでビットマップを描画する。これにより常にクライアント領域全体にビットマップが表示されるようにしている。
このコードを含むプロジェクトを実行すると、次のようなウィンドウが表示される。
上記サンプル・コードの実行時の画面 |
この時点では何も問題ないが、このウィンドウをマウスなどでリサイズすると次のような画面となって描画が正しく行われない。
ウィンドウをリサイズした場合の画面 |
この画面はウィンドウを下方向に大きくした場合のもの。OnPaintメソッドでは無効領域に対してしか描画が行えないので、クライアント領域全体に対して描画したとしても、実際に描画されるのは(この場合には)リサイズにより広くなった部分だけである。この画面の下部で表示が層状態になっているのは、ウィンドウの枠をドラッグしてリサイズしている間にも何度か再描画が行われているためだ。 |
ウィンドウのリサイズ時には再描画が必要となるのでOnPaintメソッドが呼び出されるが、OnPaintメソッドでの描画は基本的に無効領域に対してしか行えない。上記の画面の場合には、ウィンドウをリサイズすることにより広くなった部分が無効領域である。
OnResizeメソッドによるクライアント領域全体の無効化
本来、無効領域は再描画の必要な部分をできるだけ限定して再描画時のコストを抑えるためのものだ。しかし、今回のコードのように描画内容がウィンドウのサイズに依存するような場合には、ウィンドウのリサイズ時にクライアント領域全体が無効領域となる必要がある。
ウィンドウがリサイズされたときにクライアント領域全体を無効領域とするには、ウィンドウのリサイズ時に呼び出されるOnResizeメソッドをオーバーライドして(あるいはResizeイベントのイベント・ハンドラを作成して)、フォームのInvalidateメソッドを呼び出せばよい。Invalidateメソッドは指定した領域を無効にするためのもので、メソッドにパラメータを指定しない場合には、クライアント領域全体が無効となる。
Invalidateメソッドを呼び出すOnResizeメソッドの記述例は次のようになる。
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
this.Invalidate();
}
コントロール・スタイルの設定によるリサイズ時の再描画
上記のようなOnResizeメソッドを記述せずに、フォームの「コントロール・スタイル」に「ControlStyles.ResizeRedraw」を設定しておいても同様の効果が得られる。フォームにコントロール・スタイルを設定するには、フォームのSetStyleメソッドを使用する。
this.SetStyle(ControlStyles.ResizeRedraw, true);
このメソッドの第1パラメータには、ControlStyles列挙体(System.Windows.Forms名前空間)で定義されている値を指定する。また第2パラメータでは指定したスタイルのオン/オフをbool値で指定する。
次のサンプル・コードは、上記の1行を先ほどのサンプル・コードに追加したものだ。
|
|
コントロール・スタイルの設定によりリサイズ時の再描画を行うC#のサンプル・コード | |
|
|
コントロール・スタイルの設定によりリサイズ時の再描画を行うVB.NETのサンプル・コード | |
このコードを含むプロジェクトを実行し、先ほどと同様にウィンドウをリサイズした場合の画面は次のようになる。
リサイズ時にも正しく描画されたウィンドウ |
このプログラムでは、ウィンドウをリサイズしても表示内容が乱れることはない。
ただし、ここで示したコードを実際に実行すれば分かるように、ウィンドウのリサイズ時には描画がかなりちらつく。この対処については「TIPS:背景の描画を禁止して再描画時のちらつきをなくすには?」でまとめている。
カテゴリ:Windowsフォーム 処理対象:ウィンドウ 使用ライブラリ:Formクラス(System.Windows.Forms名前空間) 使用ライブラリ:ControlStyles列挙体(System.Windows.Forms名前空間) 関連TIPS:背景の描画を禁止して再描画時のちらつきをなくすには? |
|
更新履歴 | |
|
「.NET TIPS」 |
- 第2回 簡潔なコーディングのために (2017/7/26)
ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている - 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう - 第1回 明瞭なコーディングのために (2017/7/19)
C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える - Presentation Translator (2017/7/18)
Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
|
|