Enum descriptions

Developer
Dec 18, 2010 at 5:01 PM
Edited Dec 18, 2010 at 5:13 PM

Hello,

Maybe I'm missing something, but is it possible to set a description attribute on an enumeration's fields and have the combo box show that instead?

In short, this is what I'd like to do

enum MyEnum {

[Description( "A longer description")]
ValueOne,

 [Description( "An even longer description")]
ValueTwo,

}

In EnumValuesConverter, there is the GetEnumDescriptions() method, but the call to it has been commented and replaced with just Enum.GetValues(). enabling the code results in a stackoverflow. Is this feature a work-in-progress?

Thanks,

P

Coordinator
Dec 18, 2010 at 10:16 PM

I just added support for DescriptionAttribute on the Enum properties. It is supported both for the ComboBoxes and RadiobuttonLists. See the "FeaturesDemo" example.

I used a "EnumDescriptionConverter" that takes an enum value, gets the enum type, then iterates all the enum's fields to find the description. Let me know if you know a better way to do this :)

Another issue would be how to localize the DescriptionAttributes. Does anyone know?

Developer
Dec 19, 2010 at 9:33 AM

Thanks!

Localization would have to be done using a keyword for each field, then retrieving the actual string in a lookup table.

Developer
Dec 19, 2010 at 10:28 AM

Instead of using multiple foreach() and returns, the Convert method can be written like this, using LINQ.

public object Convert( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture )
{
// Prepare default result
string result = value.ToString();

	// Select the matching field and only accept one hit - enums with same value cannot be differentiated
var query = from f in value.GetType().GetFields( BindingFlags.Static | BindingFlags.GetField | BindingFlags.Public )
where f.GetValue( null ).Equals( value )
select f;

if( query.Count() == 1 ) {
// Single hit - find the Description attribute, allow only one hit
FieldInfo fi = query.First();

var attribQuery = from attrib in fi.GetCustomAttributes( typeofDescriptionAttribute ), true )
  select attrib as DescriptionAttribute;

if( attribQuery.Count() == 1 ) {
// The matching attribute has been found.
result = attribQuery.First().Description;
}
}
return result;
}

 

Coordinator
Dec 19, 2010 at 12:25 PM

hi Per, thanks for the suggestion. I agree this can be better with some LINQ. My personal preference is not use the query syntax, and I changed to

        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            var enumType = value.GetType();
            var field = enumType.GetFields(BindingFlags.Static | BindingFlags.GetField | BindingFlags.Public).First(f => f.GetValue(null).Equals(value));
            var descriptionAttribute = field.GetCustomAttributes<DescriptionAttribute>(true).FirstOrDefault();
            return descriptionAttribute != null ? descriptionAttribute.Description : value;
        }

The GetCustomAttributes is an extension method. 

Can we guarantee that we don't get any null exceptions here?

Developer
Dec 19, 2010 at 2:03 PM
objo wrote:

Can we guarantee that we don't get any null exceptions here?

My code sample checked that we got at least one hit, thus avoiding any nulls. Your call to First() is a potential null-ref exception if there are no returned fields.

This should be safe

public object Convert( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture )
{
// Default, non-converted result.
string result = value.ToString();

var field = value.GetType().GetFields( BindingFlags.Static | BindingFlags.GetField | BindingFlags.Public ).FirstOrDefault( f => f.GetValue( null ).Equals( value ) );

if( field != null ) {
var descriptionAttribute = field.GetCustomAttributes<DescriptionAttribute>( true ).FirstOrDefault();
if( descriptionAttribute != null ) {
// Found the attribute, assign description
result = descriptionAttribute.Description;
}
}

return result;
}

 

Coordinator
Dec 19, 2010 at 3:29 PM

Yes, you are right, it is possible to get a null exception there if you have an empty enum type...

I also got a stack overflow error when using the empty enum. Will look into it later. Is anybody using empty enum types?

Developer
Dec 19, 2010 at 3:53 PM

No, empty enums should be very rare as they are of no use. But better safe than sorry...

Coordinator
Dec 20, 2010 at 5:25 PM

I just included your patch, thanks.