Enum description TypeConverter
Submitted by Tomasz Paprocki on 10 February, 2011 - 11:19
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.
Implementation
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.
EnumDescriptionTypeConverter class
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
Usage example
EnumDescriptionTypeConverter class is used here as default type converter
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
Comments
not working
I use mvc 4
Can you please paste error
Can you please paste error you get?
Corrected! Thanks for your
Corrected! Thanks for your submission!
Small VB.Net Err
Canned VB to C# converters routinely mess a few things up. In the GetEnumValue function, this line:
foreach (var fieldInfo in fields)
is incorrectly converted to
For Each fieldInfo As var In fields
Well, var is not a proper type....
'fields' is an array of objects so this will work:
For Each fieldInfo As Object In fields
But I suspect the best way is:
For Each fieldInfo As System.Reflection.FieldInfo In fields
or
For Each fieldInfo As FieldInfo In fields
if System.Reflection is imported
Both seem to work
HTH and THANKS!
Post new comment