C#, WPF. In a WPF application I have got classes originally from WinForms, which have TypeConverters
and corresponding decorators. From the information I can find online it seems that TypeConverter
is not universally supported and tends to be mainly used in Winforms. But I have not been able to find a clear and simple explanation of its scope/applicability in WPF.
I have created the following minimal example. Latitude
and Longitude
are doubles
and I would like them to appear in an xceed PropertyGrid
formatted as strings
by (existing) TypeConverter
. In the simplest case this formatting would be adding a degree symbol, but there are also conversions between different units of measurement.
Here the TypeConverter
is clearly not being used. I see "1" and "2" in the PropertyGrid
and "1" in the Textbox
.
Should it work this way, or do I need to rewrite in a more WPF-centric way (e.g. ValueConverter:IValueConverter
)?
<Window x:Class="PropertyGridTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:PropertyGridTest"
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<StackPanel Orientation="Vertical">
<xctk:PropertyGrid Name="propertyGrid"/>
<TextBox Name="textBox" Text="{Binding Path=Latitude}"/>
</StackPanel>
</Grid>
</Window>
namespace PropertyGridTest
{
public class Foo {
[TypeConverter(typeof(DegreesTypeConverter))]
public double Latitude { get; set; } = 1.0;
[TypeConverter(typeof(DegreesTypeConverter))]
public double Longitude { get; set; } = 2.0;
}
public partial class MainWindow : Window
{
Foo bar = new Foo();
public MainWindow()
{
InitializeComponent();
propertyGrid.AutoGenerateProperties = true;
propertyGrid.SelectedObject = bar;
textBox.DataContext = bar;
}
}
public class DegreesTypeConverter : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof(string);
}
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
return destinationType == typeof(string);
}
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
return (value is string) ? 999.0 : 0.0;
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
return (destinationType == typeof(string)) ? "[formatted string]" : "";
}
}
}
Should it work this way, or do I need to rewrite in a more WPF-centric way (e.g. ValueConverter:IValueConverter)?
Yes, WPF uses value converters to convert a value of a source property from one type to another. If you don't specify one, it will use a built-in converter which basically just calls ToString()
on the value. The framework will not check if the data-bound property is decorated with a [TypeConverter] attribute.
TypeConverters are however used to convert XAML strings to other types. Please refer the docs for more information about this.