コンボボックスのオーナードローはあちこちで解説されているので、そちらを参考にしてください。
DOBON.NETさん ComboBoxの項目を自分で描画する
今回参考にさせていただいたのはこちら。C#です。
Out Of Memoryさん オーナードローでデータバインドなコンボボックスのサンプル
DataSourceに設定したデータからDisplayMemberの値を取りだすところで、悩んでました。
たいへん参考になりました。ありがとうございます。
カラーコンボボックスのサンプルです。
Imports System.ComponentModel
Public Class ColorComboBox
Inherits System.Windows.Forms.ComboBox
Private _ColorMember As String
Public Property ColorMember() As String
Get
Return Me._ColorMember
End Get
Set(ByVal value As String)
Me._ColorMember = value
End Set
End Property
Public Sub New()
InitializeComponent()
'アイテムの高さが均一の描画
Me.DrawMode = Windows.Forms.DrawMode.OwnerDrawFixed
End Sub
Protected Overrides Sub OnDrawItem(ByVal e As System.Windows.Forms.DrawItemEventArgs)
'描画領域の取得
Dim rctColor As New RectangleF(e.Bounds.Left, e.Bounds.Top, CSng(e.Bounds.Width * 0.3), e.Bounds.Height)
Dim rctText As New RectangleF(rctColor.Right + CSng(e.Bounds.Width * 0.1), e.Bounds.Top, e.Bounds.Width, e.Bounds.Height)
Dim rctTextBack As New RectangleF(rctColor.Right, e.Bounds.Top, e.Bounds.Width, e.Bounds.Height)
'文字列の描画
If (e.Index <> -1) Then
'--表示する文字列の取得
Dim objTxt As Object = Me.Items(e.Index)
If (Me.DataSource IsNot Nothing) Then
Dim properties As PropertyDescriptorCollection = Me.BindingContext(Me.DataSource).GetItemProperties()
Dim prpDisplayMember As PropertyDescriptor = properties(Me.DisplayMember)
If (prpDisplayMember IsNot Nothing) Then
objTxt = prpDisplayMember.GetValue(Me.Items(e.Index))
End If
End If
Dim txt As String = System.ComponentModel.TypeDescriptor.GetConverter(objTxt).ConvertToString(objTxt)
'--表示する文字列の書式
Dim sf As StringFormat = CType(StringFormat.GenericDefault.Clone, StringFormat)
sf.Alignment = StringAlignment.Near
sf.LineAlignment = StringAlignment.Center
'--文字列領域の前景色と背景色の取得
Dim clrTxtBack As Color
Dim clrTxtFore As Color
If ((e.State And DrawItemState.Disabled) <> 0) Then
clrTxtBack = SystemColors.Window
clrTxtFore = SystemColors.GrayText
ElseIf (e.State And DrawItemState.Selected) = DrawItemState.Selected Then
If (e.State And DrawItemState.ComboBoxEdit) = DrawItemState.ComboBoxEdit Then
clrTxtBack = SystemColors.Window
clrTxtFore = Me.ForeColor
Else
clrTxtBack = SystemColors.Highlight
clrTxtFore = SystemColors.HighlightText
End If
Else
clrTxtBack = SystemColors.Window
clrTxtFore = Me.ForeColor
End If
'--文字列領域の描画
Using brush As New SolidBrush(clrTxtBack)
e.Graphics.FillRectangle(brush, rctTextBack)
End Using
Using brush As New SolidBrush(clrTxtFore)
e.Graphics.DrawString(txt, e.Font, brush, rctText, sf)
End Using
'カラーボックスの描画
'--表示するカラーの取得
Dim objClr As Object = Me.Items(e.Index)
If (Me.DataSource IsNot Nothing) Then
Dim properties As PropertyDescriptorCollection = Me.BindingContext(Me.DataSource).GetItemProperties()
Dim prpColorMember As PropertyDescriptor = properties(Me.ColorMember)
If (prpColorMember IsNot Nothing) Then
objClr = prpColorMember.GetValue(Me.Items(e.Index))
End If
End If
Dim clr As Color = CType(objClr, System.Drawing.Color)
Using backBrush As New SolidBrush(clr)
e.Graphics.FillRectangle(backBrush, rctColor)
End Using
End If
''Forcus枠の描画
'If ((e.State And DrawItemState.Focus) <> 0) Then
' e.DrawFocusRectangle()
'End If
End Sub
End Class
テストコードです。
フォームにカラーコンボボックスを2つ配置し以下のコードを実行します。
Public Class Form1
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim props As System.Reflection.PropertyInfo() = GetType(Color).GetProperties(System.Reflection.BindingFlags.Public Or System.Reflection.BindingFlags.Static)
'ItemsプロパティにColorオブジェクトを追加
Dim items As New List(Of Object)
For Each prop As System.Reflection.PropertyInfo In props
If (prop.PropertyType IsNot GetType(Color)) Then
Continue For
End If
Dim color As Color = CType(prop.GetValue(Nothing, Nothing), Color)
If (color = color.Transparent) Then
Continue For
Else
items.Add(color)
End If
Next
Me.ColorComboBox1.Items.AddRange(items.ToArray)
'DataSourceにDataTableを指定
Dim dt As New DataTable()
dt.Columns.Add("Cd", GetType(Integer))
dt.Columns.Add("Color", GetType(Color))
dt.Columns.Add("Name", GetType(String))
Dim cd As Integer = 1
For Each prop As System.Reflection.PropertyInfo In props
If (prop.PropertyType IsNot GetType(Color)) Then
Continue For
End If
Dim color As Color = CType(prop.GetValue(Nothing, Nothing), Color)
If (color = color.Transparent) Then
Continue For
Else
dt.Rows.Add(cd, color, color.Name)
cd += 1
End If
Next
Me.ColorComboBox2.ValueMember = "Cd"
Me.ColorComboBox2.DisplayMember = "Name"
Me.ColorComboBox2.ColorMember = "Color"
Me.ColorComboBox2.DataSource = dt
End Sub
End Class




