.NET TIPS ListBoxコントロールのオーナー描画(高さ固定)により画像を一覧表示するには?デジタルアドバンテージ 遠藤 孝信2005/08/19 |
|
|
Windowsアプリケーションのリストボックス(ListBoxコントロール)では、その項目として文字列を利用するのが一般的であるが、「オーナー描画」(オーナードロー)と呼ばれる機能により、独自に項目を描画することもできる。
本稿では、このオーナー描画を利用して、以下のようにリストボックスに画像を一覧表示する方法について解説する。
オーナー描画によりリストボックスに画像を表示するサンプル・アプリケーションの実行画面 |
ボタンをクリックすることにより、特定のディレクトリに格納されているJPEG画像を一覧表示する。各項目の高さは一定であり、ここでは画像全体が1つの項目内に収まるように縮小(あるいは拡大)して表示している。画面は上から2番目の項目を選択しているところ。 |
なお、ListBoxコントロールのオーナー描画では、表示する項目の高さを固定(一定)にするか、可変(項目によって高さが異なる)にするかを選択することができるが、本稿では高さが固定の場合についてのみ解説する。高さを可変にする方法については「TIPS:ListBoxコントロールのオーナー描画(高さ可変)により画像を一覧表示するには? 」で解説している。
ListBoxコントロールのプロパティ設定
ListBoxコントロールでオーナー描画(高さ固定)を利用するには、まずDrawModeプロパティにDrawMode.OwnerDrawFixed(System.Windows.Forms名前空間のDrawMode列挙体の値)を設定する。これにより、各項目を描画する必要が生じた場合にDrawItemイベントが発生するようになる。
項目の高さはItemHeightプロパティにより指定できる(最大255まで)。
項目の追加
次にListBoxコントロールのItemsプロパティに対してAddメソッドにより項目を追加していく。文字列のみのリストボックスの場合は、Addメソッドのパラメータに、項目として表示したい文字列を渡すが、オーナー描画の場合には任意のオブジェクトでよい(詳細は後述)。
後掲するサンプル・プログラムでは、以下のように項目として描画する画像(Imageオブジェクト)をAddメソッドにより順に追加している。
listBox1.Items.Add(<Imageオブジェクト>)
このようにした場合、項目を追加した順番にインデックス番号が割り振られるので、そのインデックス番号を使って任意のImageオブジェクトを次のようにして取り出すことができる(C#の場合。VB.NETの場合はサンプル・プログラムを参照)。
Image thumbnail = (Image)listBox1.Items[<インデックス番号>];
あるいは、表示する画像のImageオブジェクトを配列などで保持しておき、そのインデックス番号をAddメソッドによりItemsプロパティに追加してもよい。
項目の描画時に発生するDrawItemイベント
上述したように、項目の描画が必要になった場合には、項目ごとにDrawItemイベントが発生する。このイベントのイベント・ハンドラでは、メソッドのパラメータとして渡されるDrawItemEventArgsクラス(System.Windows.Forms名前空間)のオブジェクトのプロパティから、以下のようなオブジェクトにアクセスできる。
プロパティ名 | 概要 |
Index | 描画すべき項目のインデックス番号 |
Bounds | 項目を描画する領域を示す四角形(Rectangleオブジェクト) |
Graphics | 描画対象となるGraphicsオブジェクト。例えばGraphics.DrawImageメソッドを使うとImageオブジェクトを描画できる |
画像の描画に最低限必要となるDrawItemEventArgsクラスのプロパティ | |
これ以外のプロパティについてはリファレンス・マニュアルを参照していただきたい。 |
またDrawItemEventArgsクラスには次のようなメソッドが用意されている。
メソッド名 | 概要 |
DrawBackground | 項目の背景を背景色で塗りつぶす。選択されている項目に対しては強調表示のための色で塗りつぶされる。このメソッドは画像を描画する前に呼び出す必要がある |
DrawFocusRectangle | 描画している項目にフォーカスがある場合に、それを示す四角形(枠)を描画する(初期状態などではフォーカスがあっても選択されているとは限らない) |
DrawItemEventArgsクラスのメソッド |
通常、DrawItemイベント・ハンドラでは、まずDrawBackgroundメソッドを呼び出し、次に項目の描画を行い、最後にDrawFocusRectangleメソッドを呼び出せばよい。
オーナー描画によりリストボックスに画像を表示するサンプル・アプリケーション
以下に、冒頭で示したサンプル・アプリケーションのコードを示す。
このコードを実行するには、Visual Studio .NETでWindowsアプリケーションを新規作成し、ListBoxコントロール、Buttonコントロールをフォームに配置しておく必要がある。そして、配置したButtonコントロールのClickイベントのハンドラとしてbutton1_Clickメソッドを、ListBoxコントロールのDrawItemイベントのハンドラとしてlistBox1_DrawItemメソッドを指定する。
|
||
オーナー描画によりリストボックスに画像を表示するコード(上:C#、下:VB.NET) |
このコードでは、ListBoxコントロールのScrollAlwaysVisibleプロパティをtrueにして常時リストボックスのスクロールバーを表示している点に注意してほしい。このプロパティがfalseの場合、リストボックス内の項目に応じて自動的にスクロールバーが表示されるのだが、そうするとDrawItemイベント・ハンドラで描画する画像のサイズがスクロールバーの有無により一定にならない。
ここでは最初からスクロールバーを表示してリストボックス内の領域を固定幅にすることにより、表示する画像のサムネイル画像を項目の追加時に作成できるようにしている。このようにすることにより、オリジナルの画像をメモリ上から破棄(Disposeメソッドを呼び出す)できる。これは大きな画像を扱うときにメモリの節約になる。
なおデフォルトではListBoxコントロールのIntegralHeightプロパティがtrueとなっているため、ListBoxコントロールの高さはItemHeightプロパティの倍数に自動的に調節される。IntegralHeightプロパティをfalseにすればコントロールの高さを任意に設定できる。
カテゴリ:Windowsフォーム 処理対象:ListBoxコントロール 使用ライブラリ:ListBoxコントロール(System.Windows.Forms名前空間) 使用ライブラリ:DrawItemEventArgsクラス(System.Windows.Forms名前空間) 使用ライブラリ:DrawMode列挙体(System.Windows.Forms名前空間) 関連TIPS:ListBoxコントロールのオーナー描画(高さ可変)により画像を一覧表示するには? |
|
「.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用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
|
|