0

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]" : "";
        }
    }

}
wotnot
  • 261
  • 1
  • 12
  • TypeConverters can of course be used in WPF. They are not a WinForms-specific concept. You would however need to apply the TypeConverterAttribute to the target property of a Binding, not its source (like you did). Since you are binding the Text property of a TextBox, that will obviously not be possible. Use a Binding Converter instead: https://learn.microsoft.com/en-us/dotnet/desktop/wpf/data/how-to-convert-bound-data?view=netframeworkdesktop-4.8 – Clemens Oct 15 '20 at 14:14
  • Not sure how much WPF honors those attributes. To be sure I would write the proper `IValueConverter`, whose internal implementation simply delegates to the existing `TypeConverter` under the cover. – Alejandro Oct 15 '20 at 14:15

1 Answers1

1

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.

mm8
  • 163,881
  • 10
  • 57
  • 88
  • Thanks - makes sense. How then would I apply a value converter to an xceed property grid? I don't specify the individual bindings. I just set the SelectedObject property and the control does the rest. – wotnot Oct 15 '20 at 17:52
  • The PropertyGrid supports ```DataTemplate``` for formatting. So maybe I need a ```ValueConverter``` within a ```DataTemplate```, targetting the specific properties which it applies to? – wotnot Oct 16 '20 at 10:19
  • 1
    @wotnot: Use an [EditorTemplate](https://stackoverflow.com/questions/50443733/xceed-propertygrid-customizing-integerupdown). – mm8 Oct 19 '20 at 12:44