Search code examples
c#vb.netwinformsenumspropertygrid

Force UITypeEditor to display a initial value for a Enum type


I have a class with name EnumFlagsEditor that inherits from UITypeEditor in order to design a type editor capable to edit a Enum with FlagsAttribute, by using a custom CheckedListBox, and also to be able edit a normal Enum too within the same custom editor.

In the overriden UITypeEditor.GetEditStyle method, I verify whether or not the source Enum has the FlagsAttribute set. If the Enum type has this attribute class, then I return UITypeEditorEditStyle.DropDown to diplay my custom CheckedListBox. If does not have it, I return UITypeEditorEditStyle.Modal and .NET Framework does the rest using the default editor to edit Enums using a default ComboBox to display and select the Enum values/names.

The problem is, the default built-in editor in .NET framework class library to edit a normal Enum, I noticed it searchs for a Enum name with value 0 to display it as default, and If it does not found it, throws a System.ArgumentException and does not display a default value.

Take as example this Enum:

public enum TestEnum {
    a = 1,
    b = 2,
    c = 4
}

That will throw a System.ArgumentException in the editor of a property grid and will not display a default value, because default .NET Framework editor for a Enum expects a value of 0 inside the Enum...

enter image description here

Now, using the System.DayOfWeek Enum to see the difference:

enter image description here

DayOfWeek.Sunday (0) is selected by default so any exception is thrown.

Then, in my EnumFlagsEditor class I would like to prevent this behavior. I want the editor to show a default value in the property grid for my editor. I don't care about the exception, but I would like to display a specific, initial value... to be more exact, the smallest defined value in the source Enum.

How can I do this?.


Solution

  • This is not a UITypeEditor issue, but a TypeConverter issue. What you can do is derive from the standard EnumConverter class, like this:

    [TypeConverter(typeof(MyEnumConverter))]
    public enum TestEnum
    {
        a = 1,
        b = 2,
        c = 4
    }
    
    public class MyEnumConverter : EnumConverter
    {
        public MyEnumConverter(Type type)
            : base(type)
        {
        }
    
        public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
        {
            try
            {
                return base.ConvertTo(context, culture, value, destinationType);
            }
            catch
            {
                if (destinationType == typeof(string))
                {
                    // or whatever you see fit
                    return "a";
                }
                throw;
            }
        }
    }
    

    PS: you can avoid the exception catch and do your own conversion, but it may be more difficult than it looks in the general case (depends on enum underlying type, etc.).