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