Easy multi-column dropdown vb.net

For a long time (off and on) I've been looking for an easy to implement multi column dropdown control. Just yesterday I found a knowledge base article with a code snippet on Microsoft the original link is here. Well, in my application I needed to use more than just one multi column combo, so I modified the code snipped to a class that I could call from anywhere in my application.


In my form_load event I set the draw mode of the combobox I'm going to have multiple columns with.

    Private Sub Form_Load(sender As Object, e As EventArgs) Handles Me.Load

        DataTableAdapter.Fill(Me.DData.DataTable) ' The data that is bound to combobox

        ComboBox1.DrawMode = DrawMode.OwnerDrawFixed
    End Sub

Then in the Combobox Drawitem event I get the field names I want in the column list, these fields must be in the dataset I've already bound to the control from the properties settings. Remember to adjust the "Dropdown width" to account for the space needed to show all your column data.

    Private Sub combobox1_DrawItem(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DrawItemEventArgs) Handles combobox1.DrawItem

        Dim cF As New CboFunc ' Call to my Class
        Dim MyFields As String() = {"ClerkNo", "Type", "County"} ' Fields I want in coluns        
        Dim cbo As ComboBox = sender
        cF.MultiColumnCBO(sender, e, cbo, MyFields) ' 
    End Sub

and then here is the class that is called:

Public Class CboFunc

    Public Sub MultiColumnCBO(ByVal sender As System.Object,
                               ByVal e As System.Windows.Forms.DrawItemEventArgs, cbo As ComboBox, sFieldList() As String)

        '  Usage: 
        '           'DrawItem Event from a databound combo
        ' Call From: 
        '   Sub ComboBox_DrawItem(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DrawItemEventArgs) _
        '                           Handles Combobox.DrawItem
        '   Dim cF As New CboFunc
        '   ' DrawItem Event from a databound combo
        '   Dim MyFields As String() = {"Field1", "Field2", "Field3", etc.} 'Field list of columns to display
        '   ' Then call this procedure:
        '   cF.MultiColumnCBO(sender, e, ComboBox, MyFields)
        '   End Sub
        '   Note: Make sure you set the DropDown width of the combo wide enough to show enough of your column data.

        ' Draw the default background
        ' The ComboBox is bound to a DataTable,
        ' so the items are DataRowView objects.
        Dim drv As DataRowView = CType(cbo.Items(e.Index), DataRowView)
        Dim NumColumns As Integer = sFieldList.Count
        ' Get the bounds for the first column
        Dim TotalColRectangle As Rectangle = e.Bounds
        Dim Col As Integer = 0
        TotalColRectangle.Width = TotalColRectangle.Width / NumColumns
        ' Tried For/Next but would cause a "Out of Memory Error"
        Do While Col < NumColumns
            ' Retrieve the value of each column.
            Dim MyField As String = drv(sFieldList(Col)).ToString()
            TotalColRectangle.X = (TotalColRectangle.Width * Col)
            ' Draw the text on the column
            Using sb As SolidBrush = New SolidBrush(e.ForeColor)
                e.Graphics.DrawString(MyField, e.Font, sb, TotalColRectangle)
            End Using

            ' Draw a line to isolate the columns 
            Using p As Pen = New Pen(Color.Black)
                e.Graphics.DrawLine(p, TotalColRectangle.Right, 0, TotalColRectangle.Right, TotalColRectangle.Bottom)
            End Using
            Col += 1

    End Sub

End Class

and that's it, how cool is that! 

I recently found another control like this on Code Project, it has a few more features (column width settings). Check it out at: Click here