特别是当值不连续时,您需要为控件提供一种将名称映射到相关值的方法。一旦您将
Enum.GetValues
或名称发布到CBO,它们就变得分离了。
您可以使用类似于
KeyValuesPair(of String, Int32)
的内容,其中名称用作TKey,而值用作TValue。泛型使其看起来比实际复杂。由于键始终为
String
,而值通常为
Int32
,因此我倾向于为此使用简单的
NameValuePair
类:
Public Class NameValuePair
Public Property Name As String
Public Property Value As Int32
Public Sub New(n As String, v As Int32)
Name = n
Value = v
End Sub
Public Overrides Function ToString() As String
Return String.Format("{0}", Name)
End Function
End Class
这将把任何名称与任何值关联起来。最重要的是,您可以控制ToString()
的显示内容。在这种情况下,名称和值都来自一个枚举; 一种创建列表或数组的简单方法:
Private Enum Stooges
Moe = 9
Larry = 99
Curly = 45
Shemp = 65
CurlyJoe = 8
End Enum
' method to convert any Enum to a collection of Named-Value pairs
Private Function EnumToPairsList(e As Type) As List(Of NameValuePair)
Dim ret As New List(Of NameValuePair)
Dim vals = [Enum].GetValues(e)
Dim names = [Enum].GetNames(e).ToArray
For n As Int32 = 0 To names.Count - 1
ret.Add(New NameValuePair(names(n), CType(vals.GetValue(n), Int32)))
Next
Return ret
End Function
EnumsToPairsList
可以返回一个数组,或根据需要使用 KeyValuePair
。当存在 Description
时,它可以扩展为使用描述替代名称。使用方法如下:
cbox1.DataSource = EnumToPairsList(GetType(Stooges))
cbox1.DisplayMember = "Name" ' use "Key" for a KVP
cbox1.ValueMember = "Value"
' set a value:
cbox1.SelectedValue = Convert.ToInt32(Stooges.Shemp)
使用方法
由于您已将枚举包装在NVP类中,因此每个SelectedItem
都会被包含在一个Object
中。使用这样的DataSource
时,通常会在SelectedValueChanged
事件中进行操作并检查SelectedValue
。这是它的主要目的:向用户显示名称,但在代码中返回枚举值。
唯一的“技巧”是需要将其强制转换回您的枚举:
Private Sub cbox1_SelectedValueChanged(...
Dim eItem As Stooges = CType(cbox1.SelectedValue, Stooges)
Console.WriteLine(eItem)
Console.WriteLine(eItem.ToString)
45
卷曲的
如果您坚持使用 SelectedItem
,您将不得不从 Object
转换为 NameValuePair
,获得 Value,然后将其转换为枚举类型。
通常有用的是保留数据源的副本,以便它不仅作为控件数据源而且还存在于其他地方:
Private StoogesDS As List(Of NameValuePair)
...
StoogesDS = EnumsToPairsList(GetType(Stooges))
cbox1.DataSource = StoogesDS
这使得即使表单不存在,您的代码仍然可以使用该集合。如上所述,现在每个项目都是一个
NameValuePair
对象。
cbox1.SelectedItem = StoogesDS.FirstOrDefault(Function(z) z.Name = Stooges.Shemp.ToString())
SelectedIndex
来实现所需的效果,但是这是因为巧合的是项目的索引与枚举值匹配。当枚举值与索引不同时会发生什么? - TobyFooComboBox.SelectedItem = Foo.Bar
当它们不是简单的{0,1,2}值时,使用类型设置Value和Displaymember。 - Ňɏssa Pøngjǣrdenlarp