I found a couple of solutions on the DevExpress website for how to use the ComboBoxEdit component the way I wanted, however, none of them seemed to provide a smooth transition from the WinForms databound ComboBox to the DevExpress counterpart. So using some fo the examples that I found, reading through the help and reflecting on the subject for a whole five minutes... here is what I ended up with.
Option Explicit On
Option Strict On
Option Infer On
Imports System.ComponentModel
<ProvideProperty("DisplayMember", GetType(Control))> _
<ProvideProperty("ValueMember", GetType(Control))> _
<ProvideProperty("DataSource", GetType(Control))> _
Public Class ComboBoxEditEx
Inherits DevExpress.XtraEditors.ComboBoxEdit
Private m_valueMember As String
Private m_displayMember As String
<Category("Data")> _
<Description("Indicate the property to display for the items in this control.")> _
Public Property DisplayMember() As String
Get
Return m_displayMember
End Get
Set(ByVal value As String)
m_displayMember = value
End Set
End Property
<Category("Data")> _
<Description("Indicates the property to use as the actual value for the items in the control.")> _
Public Property ValueMember() As String
Get
Return m_valueMember
End Get
Set(ByVal value As String)
m_valueMember = value
End Set
End Property
<Category("Data")> _
<Description("Indicates the list that this control will use to get its items.")> _
Public WriteOnly Property DataSource() As DataTable
Set(ByVal value As DataTable)
Dim item As New ComboItem(Me.ValueMember, Me.DisplayMember)
item.SetDataSource(Me, value)
End Set
End Property
<Browsable(False)> _
Public Property SelectedValue() As Object
Get
Dim item As New ComboItem(ValueMember, DisplayMember)
Return item.GetItemValue(Me)
End Get
Set(ByVal value As Object)
Dim item As New ComboItem(Me.ValueMember, Me.DisplayMember)
item.SelectItem(Me, value)
End Set
End Property
<Browsable(False)> _
Public ReadOnly Property Items() As DevExpress.XtraEditors.Controls.ComboBoxItemCollection
Get
Return Me.Properties.Items
End Get
End Property
End Class
Friend Class ComboItem
Private m_value As Object
Private m_displayText As String
Friend Sub New(ByVal valueMember As Object, ByVal displayMember As String)
m_value = valueMember
m_displayText = displayMember
End Sub
Public Overrides Function ToString() As String
Return m_displayText
End Function
Friend ReadOnly Property Value() As Object
Get
Return m_value
End Get
End Property
Friend Sub SetDataSource(ByRef control As ComboBoxEditEx, ByVal dt As DataTable)
For Each row As DataRow In dt.Rows
Dim item As ComboItem = New ComboItem(row.Item(control.ValueMember), CStr(row.Item(control.DisplayMember)))
control.Properties.Items.Add(item)
Next
End Sub
Friend Function GetItemValue(ByRef control As ComboBoxEditEx) As Object
Dim item As ComboItem = TryCast(control.SelectedItem, ComboItem)
If item Is Nothing Then
Return Nothing
Else
Return item.Value
End If
End Function
Friend Sub SelectItem(ByRef control As ComboBoxEditEx, ByVal value As Object)
Dim index As Integer = 0
For Each obj As Object In control.Properties.Items
Dim item As ComboItem = TryCast(obj, ComboItem)
If item IsNot Nothing AndAlso _
item.Value.Equals(value) Then
Exit For
Else
index += 1
End If
Next
If index >= control.Properties.Items.Count Then
control.SelectedIndex = -1
Else
control.SelectedIndex = index
End If
End Sub
End Class
The overall goal was to provide a seemless transition (read: drop in replacement) for the comboboxes I already had on existing forms to migrate to use all devexpress controls since I wanted to take advantage of the skinning tech in XtraForm. So what I needed was an easy way to take the existing datatables I had bound to WinForms ComboBox's, the code already used to assign (SelectedValue and SelectedIndex depending on circumstances). So far this has worked out pretty nicely. If you are in the same situation... here you go...