Does XamlServices honor ValueConverterAttribute?

99 views Asked by At

I'm using XAML as serialization mechanism (for configuration, it's not a WPF control) and I want to use a custom ValueSerializer. Please ignore poor implementation, it's just MCVE.

This is the type for which I want the custom serializer:

[ValueSerializer(typeof(PositionSerializer))]
public sealed class Position
{
    public double X { get; set; }
    public double Y { get; set; }
}

This is the custom serializer:

public sealed class PositionSerializer : ValueSerializer
{
    public override bool CanConvertFromString(string value, IValueSerializerContext context)
    {
        return true;
    }

    public override object ConvertFromString(string value, IValueSerializerContext context)
    {
        if (String.IsNullOrWhiteSpace(value))
            return new Position();

        string[] parts = value.Split(',', ' ');
        return new Position
        {
            X = Parse(parts[0]),
            Y = Parse(parts[1])
        };
    }

    private static double Parse(string value)
        => Double.Parse(value, NumberStyles.Number, CultureInfo.InvariantCulture);
}

This is the container:

public sealed class Test
{
    public Position Location { get; set; }
}

To deserialize the object I use this code:

var test = (Test)System.Xaml.XamlServices.Load(@"c:\test.xaml");

And test.xaml is simply:

<Test xmlns="clr-namespace:test;assembly=test" Location="2,3"></Test>

When running this code I get:

System.Xaml.XamlObjectWriterException: Set property 'test.Test.Location' threw an exception. ---> System.ArgumentException: Object of type 'System.String' cannot be converted to type 'test.Position'.

Same result with:

<Test xmlns="clr-namespace:test;assembly=test">
  <Test.Location>2,3</Test.Location>
</Test>

Even applying [ValueSerializer(typeof(PositionSerializer))] directly on Test.Location property does not change anything. Using a TypeConverter works as expected but I can't do it (and I'm curious to know why this does not work).

Consistently it's also ignored when serializing with XamlServices.Save() (obviously adding the ConvertToString() and CanConvertToString() methods.)

0

There are 0 answers