Enum Foo Bar Baz End Enum Private Sub Form1_Load(sender As Object,e As EventArgs) Handles MyBase.Load FooComboBox.DataSource = [Enum].GetValues(GetType(Foo)) End Sub
我想在给定时间更改所选值
Private Sub FooBar() FooComboBox.SelectedValue = Foo.Bar End Sub
但这引发了一个例外:
An unhandled exception of type ‘System.InvalidOperationException’ occurred in System.Windows.Forms.dll
Additional information: Cannot set the SelectedValue in a ListControl with an empty ValueMember.
检查ComboBox我确实可以看到ValueMember属性为空.但是当我读取时,SelectedValue等于当前所选项目的预期值,这表示ValueMember被设置为预期的枚举值.
A)如果未设置ValueMember属性,SelectedValue中的值来自何处?
B)如果绑定导致SelectedValue包含正确的值,为什么翻盖不能以相同的方式设置它?
C)我还需要做些什么来使这个血腥的.Net工作?
请注意,确实有相当多的C#&关于这一点的WPF问题,没有人真正解释这一点,就我所看到的而言,我无法从建议的答案中找出正确的vb语法.
您可以使用KeyValuesPair(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()的显示.在这种情况下,名称和值都来自Enum;创建List或Array的简单方法:
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.它可以扩展为使用描述代替名称.使用它:
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
Curly
如果您坚持使用SelectedItem,则必须从Object转换为NameValuePair,获取Value,然后将其强制转换为Enum Type.
保留数据源的副本通常很有用,因此它位于除了作为控制数据源之外的某个位置:
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())