【VB.NET】ComboBoxにDataSource設定用のメソッドを追加

下記のようにKeyValuePairのリストや配列を指定するだけで、DataSource/DisplayMember/ValueMemberを設定することができるメソッドをComboBoxに追加します。

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    Dim dataList As New List(Of KeyValuePair(Of String, String))()
    dataList.Add(New KeyValuePair(Of String, String)("A", "1"))
    dataList.Add(New KeyValuePair(Of String, String)("B", "2"))
    dataList.Add(New KeyValuePair(Of String, String)("C", "3"))

    ComboBoxEx1.SetData(dataList, True, True)
End Sub

Private Sub ComboBoxEx1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBoxEx1.SelectedIndexChanged
    MessageBox.Show(ComboBoxEx1.SelectedValue.ToString())
End Sub

KeyValuePairのジェネリックの2番目の型を変更することで、ValueMemberに設定する型を変更することもできます。

Public Class ComboBoxEx
    Inherits ComboBox

    ''' <summary>
    ''' データを設定する。
    ''' </summary>
    ''' <param name="items">表示テキストと値の組み合わせ項目リスト。</param>
    ''' <param name="addEmpty">先頭に空白を追加するかどうか。</param>
    ''' <param name="autoSize">内容に合わせて幅を自動調整するかどうか。</param>
    Public Sub SetData(ByVal items As IEnumerable(Of KeyValuePair(Of String, String)), _
                       ByVal addEmpty As Boolean, _
                       ByVal autoSize As Boolean)
        ' 設定データクリア
        ClearData()

        Dim itemList As List(Of KeyValuePair(Of String, String)) = items.ToList()

        ' 空アイテムの追加
        If addEmpty Then
            itemList.Insert(0, New KeyValuePair(Of String, String)("", ""))
        End If

        ' バインド
        MyBase.DisplayMember = "Key"
        MyBase.ValueMember = "Value"
        MyBase.DataSource = itemList

        ' 幅の自動調整
        If autoSize Then
            If itemList.Count = 0 Then
                Return
            End If

            Dim maxWidth As Integer = 0
            Dim g As Graphics = MyBase.CreateGraphics()

            ' 表示テキストの最大長+余白分の幅
            MyBase.Width = CInt(items.Select(Function(item) g.MeasureString(Convert.ToString(item.Key), MyBase.Font).Width).Max()) + 20
        End If
    End Sub

    ''' <summary>
    ''' 設定データをクリアする。
    ''' </summary>
    Public Sub ClearData()
        If MyBase.DataSource Is Nothing Then
            ' アイテムクリア
            MyBase.Items.Clear()
        Else
            ' データソースクリア
            MyBase.DataSource = Nothing
        End If
    End Sub

End Class