.net – 如何为Enum绑定的ComboBox设置SelectedValue

前端之家收集整理的这篇文章主要介绍了.net – 如何为Enum绑定的ComboBox设置SelectedValue前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我已经将ComboBox绑定到这样的枚举
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语法.

特别是当值不是连续的时,您需要为控件提供一种方法,将Name“映射”到相关值.一旦您将Enum.GetValues或名称发布到CBO,它们就会变得分离.

您可以使用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())

猜你在找的VB相关文章