问题描述
如何将枚举的格式化字符串描述绑定到组合框?我希望组合框显示说明,而不是枚举.
我有一个这样的枚举:
公共枚举三明治< ComponentModel.Description(火腿三明治")>火腿三明治< ComponentModel.Description(鲁本"))>鲁本< ComponentModel.Description("Po’Boy"))>PoBoy< ComponentModel.Description(烤奶酪")>烤奶酪结束枚举
在描述字符串已绑定到组合框之后,我可以使用此功能将所选项目转换回枚举:
公共函数GetEnumFromDescriptionAttribute(Of T)(描述为字符串)作为T昏暗的类型作为类型= GetType(T)如果不是type.IsEnum然后抛出新的InvalidOperationException()万一对于每个fi作为Reflection.FieldInfo in type.GetFields()昏暗的descriptionAttribute为ComponentModel.DescriptionAttribute = TryCast(Attribute.GetCustomAttribute(fi,GetType(ComponentModel.DescriptionAttribute)),ComponentModel.DescriptionAttribute)如果descriptionAttribute不算什么,则如果descriptionAttribute.Description<>然后描述继续万一返回DirectCast(fi.GetValue(Nothing),T)万一如果fi.Name<>然后描述继续万一返回DirectCast(fi.GetValue(Nothing),T)下一个一无所有结束功能
但是我找不到一种将所有枚举绑定到组合框的干净方法.我知道,通常建议的解决方案是将枚举和枚举描述转换为字典,然后将其设置为cbo DisplayMember和ValueMember.但是我不知道该怎么做.
我已经就如何做到这一点完成了数十个局部解决方案.问题在于它们都是用C#编写的,在Option Strict关闭的情况下使用隐式转换,并且没有显示完整的实现.因此,对我来说,将任何解决方案都转换成.NET都是不可能的,因为我不知道将什么类型的变量定义为.
看来您的目标是覆盖Enum值的字符串表示形式.基本表示形式显示Enum的名称,在此位置要显示Enum的Description属性.
假设这是WinForm的组合框,则标准方法是使用自定义
使用 ComboBox.SelectedItem
检索所选值.
How can I bind the formatted string descriptions of an enumeration to a combobox? I want the combobox to show the descriptions, not the enum.
I have an enum like this:
Public Enum Sandwiches
<ComponentModel.Description("Ham Sandwich")> HamSandwich
<ComponentModel.Description("Reuben")> Reuben
<ComponentModel.Description("Po’ Boy")> PoBoy
<ComponentModel.Description("Grilled Cheese")> GrilledCheese
End Enum
I can use this function to convert the selected item back to an enum, after the description string has already been bound to a combobox:
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
But I cannot find a clean way to bind all of the enumerations to the combobox. I know that an often sugested solution is to convert the enums and enum descriptions to a dictionary, and then set those as the cbo DisplayMember and ValueMember. But I cannot figure out how to actually do that.,
I've ready through dozens of partial solutions on how to do this; The problem is that they are all written in C#, use implicit conversion with Option Strict turned OFF, and don't show the full implementation. So it's impossible for me to translate any of the solutions into .NET, since I have no idea what type variables have been defined as.
It appears that your goal is override the string representation of a Enum value. The base representation displays Enum's name, where-as you want to display the Enum's Description attribute.
Assuming that this is a WinForm's combobox, the standard way would be to decorate the Enum with a custom TypeConverter and override the ConvertTo
method. Using the EnumConverter Class and the basis for the custom converter minimizes the required code.
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
Modify your Enum definition to use this custom converter.
<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
Now all you need to do is load the ComboBox.Items
with Enum values.
ComboBox1.Items.AddRange(System.Enum.GetValues(GetType(Sandwiches)).Cast(Of Object).ToArray())
Use the ComboBox.SelectedItem
to retrieve the selected value.
这篇关于将枚举的所有描述绑定到组合框的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!