S h o r t S t o r i e s

// Tales from software development

Application Settings and custom types

leave a comment »

In the past I’ve sometimes created settings in the Visual Studio Settings designer that used Enum types defined in an assembly in my application. This works well enough except that I’d noticed that the Browse… function in the drop down list for the Type field was never able to display the type and instead I had to type in the full type name in the Selected type text box at the bottom of the type browser.

I’ve recently created a struct to represent the time of day. I assumed that this could be specified as type in the Settings designer but the browser not only failed to show the type but either refused to recognise the type when I entered its full name or accepted the type name but then insisted that the value must be specified using a chunk of XML.

Clearly there is some magic required to make the Settings designer and the Application Settings configuration code handle my TimeOfDay struct the way that it handles the standard .NET types.

I tried implementing some of the interfaces implemented by System.DateTime on the basis that this is also a struct and that the Settings designer handles it correctly but nothing provided what I was looking for.

Finally, a hint in another blog posting made me try implementing a TypeConverter for my TimeOfDay struct. I didn’t hold out much hope as the conversions required are string to TimeOfDay and TimeOfDay to string and the struct already implements a constructor that takes a string and a ToString method. Surely the Settings designer would use these for conversions and so what was the point of implementing a TypeConverter that does exactly the same thing ? My thinking was wrong and the TypeConverter is the solution. The implementation is simple enough:

    public class TimeOfDayConverter : TypeConverter
    {
        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
        {
            return sourceType == typeof(string);
        }
        public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
        {
            if (value is string)
            {
                  return new TimeOfDay(value as string);
            }
            return base.ConvertFrom(context, culture, value);
        }
        public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
        {
            if (destinationType == typeof(string))
            {
                TimeOfDay timeOfDay = (TimeOfDay)value;
                return timeOfDay.ToString();
            }

            return base.ConvertTo(context, culture, value, destinationType);
        }
    }

The magic is accomplished by adding a System.ComponentModel.TypeConverter attribute to the custom type that associates the TypeConverter with the type:

    [TypeConverter(typeof(TimeOfDayConverter))]
    public struct TimeOfDay : IFormattable
    {
        ...
    }

The Settings designer can now handle the TimeOfDay struct:
Settings Designer

Advertisements

Written by Sea Monkey

February 20, 2013 at 8:00 pm

Posted in Development

Tagged with ,

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: