Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vb.net 将枚举的所有描述绑定到组合框_Vb.net_Enums_Combobox - Fatal编程技术网

Vb.net 将枚举的所有描述绑定到组合框

Vb.net 将枚举的所有描述绑定到组合框,vb.net,enums,combobox,Vb.net,Enums,Combobox,如何将枚举的格式化字符串描述绑定到组合框?我希望组合框显示描述,而不是枚举 我有这样一个枚举: Public Enum Sandwiches <ComponentModel.Description("Ham Sandwich")> HamSandwich <ComponentModel.Description("Reuben")> Reuben <ComponentModel.Description("Po’ Boy

如何将枚举的格式化字符串描述绑定到组合框?我希望组合框显示描述,而不是枚举

我有这样一个枚举:

Public Enum Sandwiches
<ComponentModel.Description("Ham Sandwich")> HamSandwich
<ComponentModel.Description("Reuben")> Reuben
<ComponentModel.Description("Po’ Boy")> PoBoy
<ComponentModel.Description("Grilled Cheese")> GrilledCheese
End Enum
公共枚举三明治
火腿三明治
鲁本
波博伊
烤奶酪
结束枚举
在描述字符串已绑定到组合框后,我可以使用此函数将选定项转换回枚举:

        Public Function GetEnumFromDescriptionAttribute(Of T)(description As String) As T
        Dim type As Type = GetType(T)
        If Not type.IsEnum Then
            Throw New InvalidOperationException()
        End If
        For Each fi As Reflection.FieldInfo In type.GetFields()
            Dim descriptionAttribute As ComponentModel.DescriptionAttribute = TryCast(Attribute.GetCustomAttribute(fi, GetType(ComponentModel.DescriptionAttribute)), ComponentModel.DescriptionAttribute)
            If descriptionAttribute IsNot Nothing Then
                If descriptionAttribute.Description <> description Then
                    Continue For
                End If
                Return DirectCast(fi.GetValue(Nothing), T)
            End If
            If fi.Name <> description Then
                Continue For
            End If
            Return DirectCast(fi.GetValue(Nothing), T)
        Next
        Return Nothing
    End Function
公共函数GetEnumFromDescriptionAttribute(Of T)(描述为字符串)作为T
Dim type As type=GetType(T)
如果不是type.IsEnum,则
抛出新的InvalidOperationException()
如果结束
对于类型.GetFields()中的每个fi作为Reflection.FieldInfo
Dim descriptionAttribute As ComponentModel.descriptionAttribute=TryCast(Attribute.GetCustomAttribute(fi,GetType(ComponentModel.descriptionAttribute)),ComponentModel.descriptionAttribute)
如果descriptionAttribute不是空的,那么
如果为descriptionAttribute.Description,则为
继续
如果结束
返回DirectCast(fi.GetValue(Nothing),T)
如果结束
如果是fi.名称描述,则
继续
如果结束
返回DirectCast(fi.GetValue(Nothing),T)
下一个
一无所获
端函数
但是我找不到一种干净的方法将所有枚举绑定到combobox。我知道一个经常被建议的解决方案是将枚举和枚举描述转换为字典,然后将它们设置为cbo DisplayMember和ValueMember。但我不知道该怎么做


我已经准备好了几十个关于如何做到这一点的部分解决方案;问题是它们都是用C#编写的,在关闭Option Strict的情况下使用隐式转换,并且没有显示完整的实现。因此,我不可能将任何解决方案转换为.NET,因为我不知道变量定义为什么类型。

这是我不久前编写的一个类,用于表示
Enum
值及其描述:

导入System.ComponentModel
输入系统。反射
''' 
''包含枚举常量值和该值的友好描述(如果存在)。
''' 
''' 
''值的枚举类型。
''' 
公共类枚举描述符(共T个)
''' 
''对价值的友好描述。
''' 
私有\u描述为字符串
''' 
''枚举的常量值。
''' 
私有值作为T
''' 
''获取值的友好描述。
''' 
''' 
''一个字符串,包含值的描述属性值(如果存在);否则,将指定值名称。
''' 
作为字符串的公共只读属性描述()
得到
给我回电话
结束
端属性
''' 
''获取枚举的常量值。
''' 
''' 
''枚举描述符的泛型参数类型的枚举常量。
''' 
作为T的公共只读属性值()
得到
返回给我
结束
端属性
''' 
''创建EnumDescriptor类的新实例。
''' 
''' 
''提供描述的值。
''' 
公共子新建(ByVal值为T)
我的价值=价值
'获取描述属性。
Dim字段为FieldInfo=value.GetType().GetField(value.ToString())
Dim属性作为DescriptionAttribute()=DirectCast(field.GetCustomAttributes(GetType(DescriptionAttribute))_
假),_
DescriptionAttribute())
'使用描述属性(如果存在),否则使用值本身作为描述。
Me.\u description=If(attributes.Length=0_
value.ToString()_
属性(0)。描述)
端接头
''' 
“已覆盖”。创建对象的字符串表示形式。
''' 
''' 
''对价值的友好描述。
''' 
Public将函数ToString()重写为字符串
还给我。描述
端函数
末级
这是我刚刚写的一个简化版本:

导入System.ComponentModel
输入系统。反射
公共类枚举描述符(共T个)
作为字符串的公共只读属性描述
公共只读属性值为T
公共子新建(值为T)
价值=价值
'获取描述属性。
Dim字段=value.GetType().GetField(value.ToString())
Dim attributes=DirectCast(field.GetCustomAttributes(GetType(DescriptionAttribute),False),DescriptionAttribute())
'如果存在描述属性,则使用该属性,否则使用值本身作为描述。
Description=If(attributes.Length=0,value.ToString(),attributes(0).Description)
端接头
Public将函数ToString()重写为字符串
返回说明
端函数
末级
下面是另一个类,可用于为
枚举中的每个值存储前一个类的实例:

“”
''枚举类型的枚举描述符的集合。
''' 
''' 
''为其创建枚举描述符的枚举类型。
''' 
公共类EnumDescriptorCollection(共T个)
继承ObjectModel.Collection(属于EnumDescriptor(属于T))
''' 
''创建EnumDescriptorCollection类的新实例。
''' 
公共分新()
'使用每个枚举值的枚举描述符填充集合。
对于[Enum].GetValues(GetType(T))中作为T的每个值
添加(新的枚举描述符(共T个)(值))
下一个
端接头
末级
Imports System.ComponentModel
Imports System.Globalization
Imports System.Reflection

Public Class EnumDescriptionConverter(Of T As {Structure, IConvertible}) : Inherits EnumConverter

  Private enumDescriptions As New Dictionary(Of T, String)

  Public Sub New()
    MyBase.New(GetType(T))
    ' Since the ability to add an Enum constraint to the generic type does not exist in VB.
    ' this check is to ensure that it is an Enum.
    ' Note that normally, throwing an exception in a constructor is considered bad form, but
    ' there is no other option
    If GetType(T).IsEnum Then
      LoadEnumDescriptions()
    Else
      Throw New ArgumentException($"{GetType(T).Name} is not an Enum")
    End If
  End Sub

  Private Sub LoadEnumDescriptions()
    ' An Enum type comprises static (Shared) fields that represent the defined enum values and
    ' an instance field that holds thae actual value. so only retrieve the static fields
    ' to get the defined (named) enum members.
    For Each fi As FieldInfo In GetType(T).GetFields(BindingFlags.Public Or BindingFlags.Static)
      Dim description As String
      Dim descAttrib As DescriptionAttribute = fi.GetCustomAttribute(Of DescriptionAttribute)
      If descAttrib Is Nothing Then
        ' no description attribute so use the defined name
        description = fi.Name
      Else
        description = descAttrib.Description
      End If
      enumDescriptions.Add(CType(fi.GetValue(Nothing), T), description)
    Next
  End Sub

  Public Overrides Function ConvertTo(context As ITypeDescriptorContext, culture As CultureInfo, value As Object, destinationType As Type) As Object
    Dim ret As Object

    ' the purpose of this converter is to provide an enum's description attribute as the string representation
    ' instead of the field name as provided by the standard implemention.
    If destinationType Is GetType(String) AndAlso value IsNot Nothing Then
      Dim enumValue As T = DirectCast(value, T)
      If enumDescriptions.ContainsKey(enumValue) Then
        ret = enumDescriptions(enumValue)
      Else
        ret = enumValue.ToString(Nothing)
      End If
    Else
      ret = MyBase.ConvertTo(context, culture, value, destinationType)
    End If
    Return ret
  End Function
End Class
<TypeConverter(GetType(EnumDescriptionConverter(Of Sandwiches)))>
Public Enum Sandwiches
  <ComponentModel.Description("Ham Sandwich")> HamSandwich
  <ComponentModel.Description("Reuben")> Reuben
  <ComponentModel.Description("Po’ Boy")> PoBoy
  <ComponentModel.Description("Grilled Cheese")> GrilledCheese
End Enum
ComboBox1.Items.AddRange(System.Enum.GetValues(GetType(Sandwiches)).Cast(Of Object).ToArray())