WinForms ComboBox -> DevExpress ComboBoxEdit (migration)
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 combo box 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.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
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 seamless transition (read: drop in replacement) for the combo boxes 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 data tables I had bound to WinForms combo boxes, 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…