ComboBox OwnerDraw(オーナドロー)解説

VB Tips And Sample(HOME)(VB.NET Sample インデックス)

ComboBox OwnerDraw(オーナドロー)解説

解説すると、あれもこれもとなってしまいわかりにくいかもしれません。
ポイントは全部で10あると思います。
①ではオーナードローを行う旨を宣言しています。
オナードローというと敷居が高くて、ちょっと・・・・と思われるかもしれませんが、MSDNヘルプには大概サンプルが載っています。
それを参考にすれば、なんとなくできるのではないでしょうか?

②のような記述は、MSDNに載っているものを頼りにするわけなので、少なくとも、管理人はそれを読んでナルホドと、ComboBox1.DrawItemを書いてみることになります。

③は別方法もあるので、参考にしてください。これはイベントについて知っている必要があります。
そのイベントは④で解説しています。
イベントの決まりです。

ここまでくれば、後はMSDNヘルプのサンプルをゴリゴリ書いて、適当にコメントアウトしてみたりして、またヘルプを読みながら書いていけばなんとなくできます。


まとめとポイント
オーナードローは、結局の所、システムから呼ばれるコントロールの描画イベントを、
プログラマーがゴリゴリと書いて変更する為の機能と言えると思います。
そこで、意外に基本のキである「イベント」の理解が重要だと改めて思いました。
次回は「イベント」について解説してみたいと思います。


Public Class Form1

   

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        'プロパティーで設定するもの
        'ComboBoxStyle.DropDownList

        'DrawMode.OwnerDrawFixed() 
        'MS→リストの要素を描画を処理するのは、コードとオペレーティング システムのどちらであるかを示す値を取得または設定します。 
        'OwnerDrawFixed()は、コンボのリストは同じサイズで手動で書きますと言う事になる。

        'ItemHeight = 46 '高さはイメージリストのイメージのサイズに合わせる

        'ComboBox1.DrawItemイベントは、
        'MS→「オーナー描画 ComboBox のビジュアルな部分を変更すると発生します。」
        'とある。
        'つまり、オーナドローにした場合、ComboBox1.DrawItemイベントの中を、自分=オーナがごりごり書きます!
        'という事。

        '↓は最初に、AddHandlerする場合
        'MS→実行時にイベントをイベント ハンドラに関連付けます。
        '例 AddHandler event, AddressOf eventhandler
        'AddHandler ComboBox1.DrawItem, AddressOf ComboBox1_DrawItem

        Dim i As Integer = 0
        'せっかくなので 
        'オブジェクトを追加してみよう!()
        Do Until Me.ImageList1.Images.Count <= i
            Me.ComboBox1.Items.Add(Me.ImageList1.Images(i))
            i = i + 1
        Loop

    End Sub


    'MSDNのサンプルには以下↓の様に書かれている。こっちの方がわかりやすいかも?
    Private Sub ComboBox1_DrawItem(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawItemEventArgs) Handles ComboBox1.DrawItem
        '↓は最初に「AddHandler」しておおいたもの。
        'Private Sub ComboBox1_DrawItem(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawItemEventArgs)

        'VBのイベントの基本は下記のような形式となる
        ' Sub EventNameEventHandler(sender As Object, e As EventNameEventArgs)
        'senderはイベントの元になったオブジェクトと言えます。つまり発生源。
        'どういうことか?は、「イベント」について詳しく知る必要があります。
        '簡単にいえば、ComboBox1_DrawItemは、ComboBox1.DrawItem以外からも、呼ぶことができ、
        'その場合、たとえば「ボタンA」からか、ComboBox1から呼ばれたのかこの「sender」で調べることができると言うこと。
        'MS →EventArgs は、イベント データが格納されているクラスの基本クラスです。 

        e.DrawBackground() 'MS→描画されている項目の状態が Selected の場合、テキストが強調表示された状態で背景が描画されます。
        'MSの解説の通り、コメントアウトすると、選択点線枠のみとなってしまう。

        'イベントの発生源=コンボボックスをコンボボックスとして扱うため、型の変換。
        Dim cmb As Windows.Forms.ComboBox = CType(sender, Windows.Forms.ComboBox)

        Dim p As Point
        p.X = e.Bounds.X '左上隅横座標
        p.Y = e.Bounds.Y '左上隅の縦座標

        '項目に表示する画像
        Dim img As Image
        If e.Index > -1 Then
            img = cmb.Items(e.Index) 'コンボボックスのitem(オブジェクト)から画像を取り出します。
        Else
            img = Me.ImageList1.Images(0) 'デフォルト画像を設定。
        End If

        e.Graphics.DrawImage(img, p) '画像を描画

        Debug.Print(cmb.Items.Count.ToString)

        e.DrawFocusRectangle() 'MS→コンストラクタで指定されている境界内に、フォーカスを示す四角形を描画します。
        'これで選択範囲の外枠が描画される。


    End Sub


End Class




e.DrawFocusRectangle()をコメントアウトするとこうなる。 e.DrawBackground()をコメントアウトするとこうなる。