Universal value converter

  • Gérald Barré

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.

C#
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:

XAML
<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>

Do you have a question or a suggestion about this post? Contact me!

Follow me:
Enjoy this blog?Buy Me A Coffee💖 Sponsor on GitHub