From this article you can learn how to define and use enum description type converter so sytem will know how to handle enum to string and string to enum values (very helpful in PropertyGrid for example).
Implementation is available both in C# and VB.Net languages.
Below you can find implementation we use in Karmian Framework as enum description type converter. It can be easily extended to work also as localizable enum description type converter - Description attribute can be used as a key of localized resource.
using System; using System.ComponentModel; using System.Globalization; namespace Karmian.Core.TypeConverters { public class EnumDescriptionTypeConverter : EnumConverter { public EnumDescriptionTypeConverter(Type type) : base(type) { } public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) { return sourceType == typeof(string) || TypeDescriptor.GetConverter(typeof(Enum)).CanConvertFrom(context, sourceType); } public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { if (value is string) return GetEnumValue(EnumType, (string) value); if (value is Enum) return GetEnumDescription((Enum) value); return base.ConvertFrom(context, culture, value); } public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) { return value is Enum && destinationType == typeof(string) ? GetEnumDescription((Enum)value) : (value is string && destinationType == typeof(string) ? GetEnumDescription(EnumType, (string)value) : base.ConvertTo(context, culture, value, destinationType)); } public static string GetEnumDescription(Enum value) { var fieldInfo = value.GetType().GetField(value.ToString()); var attributes = (DescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false); return (attributes.Length > 0) ? attributes[0].Description : value.ToString(); } public static string GetEnumDescription(Type value, string name) { var fieldInfo = value.GetField(name); var attributes = (DescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false); return (attributes.Length > 0) ? attributes[0].Description : name; } public static object GetEnumValue(Type value, string description) { var fields = value.GetFields(); foreach (var fieldInfo in fields) { var attributes = (DescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false); if (attributes.Length > 0 && attributes[0].Description == description) return fieldInfo.GetValue(fieldInfo.Name); if (fieldInfo.Name == description) return fieldInfo.GetValue(fieldInfo.Name); } return description; } } }
Imports System.ComponentModel Imports System.Globalization Namespace Karmian.Core.TypeConverters Public Class EnumDescriptionTypeConverter Inherits EnumConverter Public Sub New(type As Type) MyBase.New(type) End Sub Public Overrides Function CanConvertFrom(context As ITypeDescriptorContext, sourceType As Type) As Boolean Return sourceType Is GetType(String) OrElse TypeDescriptor.GetConverter(GetType([Enum])).CanConvertFrom(context, sourceType) End Function Public Overrides Function ConvertFrom(context As ITypeDescriptorContext, culture As CultureInfo, value As Object) As Object If TypeOf value Is String Then Return GetEnumValue(EnumType, DirectCast(value, String)) End If If TypeOf value Is [Enum] Then Return GetEnumDescription(DirectCast(value, [Enum])) End If Return MyBase.ConvertFrom(context, culture, value) End Function Public Overrides Function ConvertTo(context As ITypeDescriptorContext, culture As CultureInfo, value As Object, destinationType As Type) As Object Return If(TypeOf value Is [Enum] AndAlso destinationType Is GetType(String), GetEnumDescription(DirectCast(value, [Enum])), (If(TypeOf value Is String AndAlso destinationType Is GetType(String), GetEnumDescription(EnumType, DirectCast(value, String)), MyBase.ConvertTo(context, culture, value, destinationType)))) End Function Public Shared Function GetEnumDescription(value As [Enum]) As String Dim fieldInfo = value.[GetType]().GetField(value.ToString()) Dim attributes = DirectCast(fieldInfo.GetCustomAttributes(GetType(DescriptionAttribute), False), DescriptionAttribute()) Return If((attributes.Length > 0), attributes(0).Description, value.ToString()) End Function Public Shared Function GetEnumDescription(value As Type, name As String) As String Dim fieldInfo = value.GetField(name) Dim attributes = DirectCast(fieldInfo.GetCustomAttributes(GetType(DescriptionAttribute), False), DescriptionAttribute()) Return If((attributes.Length > 0), attributes(0).Description, name) End Function Public Shared Function GetEnumValue(value As Type, description As String) As Object Dim fields = value.GetFields() For Each fieldInfo As FieldInfo In fields Dim attributes = DirectCast(fieldInfo.GetCustomAttributes(GetType(DescriptionAttribute), False), DescriptionAttribute()) If attributes.Length > 0 AndAlso attributes(0).Description = description Then Return fieldInfo.GetValue(fieldInfo.Name) End If If fieldInfo.Name = description Then Return fieldInfo.GetValue(fieldInfo.Name) End If Next Return description End Function End Class End Namespace
using System; using System.ComponentModel; using Karmian.Core.TypeConverters; namespace GoldenSharp.Common { [TypeConverter(typeof(EnumDescriptionTypeConverter))] public enum TargetFramework { [Description("Default")] Default, [Description("ISO-1")] ISO_1, [Description("ISO-2")] ISO_2, [Description("C# 3.0")] CS_3 } }
Imports System.ComponentModel Imports Karmian.Core.TypeConverters Namespace GoldenSharp.Common <TypeConverter(GetType(EnumDescriptionTypeConverter))> _ Public Enum TargetFramework <Description("Default")> _ [Default] <Description("ISO-1")> _ ISO_1 <Description("ISO-2")> _ ISO_2 <Description("C# 3.0")> _ CS_3 End Enum End Namespace