Click here to Skip to main content
15,881,812 members
Articles / Desktop Programming / WPF
Tip/Trick

WPF ValueConverter to Convert to Correct Type

Rate me:
Please Sign up or sign in to vote.
5.00/5 (5 votes)
5 Apr 2018CPOL2 min read 12.3K   11   4
Normally, there is no need to ensure that types exactly match when using a Binding. For instance, the Control property double to and int in a ViewModel

Introduction

I had developed a custom control that contained a Slider and was Binding the Slider Value property through a DependencyProperty of the same type (it could have been of Type object) through a TemplatedParent Binding to a ViewModel that had an int property for the Slider Value. What surprised me is that this did not work because a Type conversion error--apparently in this case, the TypeDescriptor was not being used to convert to the correct type. I could not just change the Type in the ViewModel because a special class was being used to retrieve and update the value, and the format this value was being stored as was int. I had worked with TypeDescriptor conversion in IValueConverter classes before, and decided I could easily fix this with a ValueConverter using a TypeDescrirptor:

C#
public class TypeValueConverter : MarkupExtension, IValueConverter
{
    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        return this;
    }

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

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return ConvertToType(value, targetType);
    }

    private static object ConvertToType(object value, Type targetType)
    {
        try
        {
            if (targetType == typeof(object)) return value;
            var converter = TypeDescriptor.GetConverter(targetType);
            return converter.ConvertFrom(value.ToString());
        }
        catch
        {
            var errorValue = value;
            throw new Exception(
                $"Failed in attempt to convert {errorValue} to type
                {targetType.Name} using TypeConverter in class TrueFalseValues");
        }
    }
}

Using the Code

As with any IValueConverter, to use it, include the Converter argument in the Binding definition. Since this class not only derives from IValueConverter, but also MarkupExtension, can directly use the converter without defining it:

XML
<local:BaseSlider Grid.Row="3"
                  Grid.Column="1"
                  Height="40"
                  HorizontalAlignment="Stretch"
                  VerticalAlignment="Center"
                  NewValue="{Binding SliderValue2.Value,
                                     Converter={local:TypeValueConverter}}" />

Points of Interest

The interesting thing about the whole problem I encountered is that I was getting a Type error when I should not have since WPF is supposed to handle basic conversions which are supported through the TypeDescriptor, and there is support between most number types, such as between int and double. In this case, I had a Generic class that kept the actual value in a Value property. What I had was a custom Control that contained a double Binding to the Slider Value property, with, in this instance, to a ViewModel int Type property. So to solve this problem in the application I was working on, I created this converter. Then I tried to reproduce the problem in a separate simplified project to include with this tip, I could not do. I even tried to move a lot of the code over, but not everything since I really did not want to have to include the Rx (Linq to Events) framework which was being used. So, it is very unlikely that someone will need this converter. At this point, I do not have a sample that will show this problem but will probably continue to work on this problem to try and reproduce the problem.

History

  • 04/05/2018: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Clifford Nelson Consulting
United States United States
Has been working as a C# developer on contract for the last several years, including 3 years at Microsoft. Previously worked with Visual Basic and Microsoft Access VBA, and have developed code for Word, Excel and Outlook. Started working with WPF in 2007 when part of the Microsoft WPF team. For the last eight years has been working primarily as a senior WPF/C# and Silverlight/C# developer. Currently working as WPF developer with BioNano Genomics in San Diego, CA redesigning their UI for their camera system. he can be reached at qck1@hotmail.com.

Comments and Discussions

 
GeneralMy vote of 5 Pin
Hyland Computer Systems8-Apr-18 7:49
Hyland Computer Systems8-Apr-18 7:49 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.