Universal value converter

Writing converters is long and annoying because you often use basic conversion from one type to another. This type of conversion can be done automatically using the TypeDescriptor.

public class UniversalValueConverter : MarkupExtension, IValueConverter
{
    private static object Convert(object value, Type targetType, System.Globalization.CultureInfo culture)
    {
        // obtain the conveter for the target type
        TypeConverter converter = TypeDescriptor.GetConverter(targetType);

        try
        {
            // determine if the supplied value is of a suitable type
            if (converter.CanConvertFrom(value.GetType()))
            {
                // return the converted value
                return converter.ConvertFrom(null, culture, value);
            }
            else
            {
                // try to convert from the string representation
                return converter.ConvertFrom(null, culture, value.ToString());
            }
        }
        catch (Exception)
        {
            return value;
        }
    }

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return Convert(value, targetType, culture);
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return Convert(value, targetType, culture);
    }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        return this;
    }
}

The converter inherits from MarkupExtension which avoids having to create a resource to use it. Here is an example of use:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication1"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <Rectangle Fill="{Binding ElementName=colorTextBox, Path=Text, Converter={local:UniversalValueConverter}}" />
        <TextBox x:Name="colorTextBox"
             Text="Red" Grid.Column="1" />

        <Rectangle x:Name="rec" Fill="Green" Grid.Row="1" />
        <TextBox Text="{Binding ElementName=rec, Path=Fill, Converter={local:UniversalValueConverter}}" Grid.Column="1" Grid.Row="1" />
    </Grid>
</Window>

Leave a reply