Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for TypeDescriptionProvider when resolving the TypeConverter used while parsing xaml files #4503

Open
nalka0 opened this issue May 11, 2021 · 2 comments

Comments

@nalka0
Copy link

nalka0 commented May 11, 2021

Issue to fix

Considering the following class :

public class Wrapper<T>
{
    public T Wrapped { get; set; }

    public override string ToString()
    {
        return $"{Wrapped.GetType()} : {Wrapped}";
    }
}

If I have an object with a property of type Wrapper<T> and want to use it in XAML like MyProperty="SomeValue" a TypeConverter is required.
Here, the TypeConverter implementation would look like :

public class WrapperConverter : TypeConverter
{
    private readonly Type wrappedType;

    public WrapperConverter(Type wrappedType)
    {
        this.wrappedType = wrappedType;
    }

    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
        return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType);
    }

    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
    {
        Type retType = typeof(Wrapper<>).MakeGenericType(wrappedType);
        var conversionResult = TypeDescriptor.GetConverter(wrappedType).ConvertFrom(context, culture, value);
        var ret = Activator.CreateInstance(retType); // var ret = new Wrapper<T>();
        retType.GetProperty(nameof(Wrapper<object>.Wrapped)).SetValue(ret, conversionResult); // ret.Wrapped = conversionResult;
        return ret;
    }
}

The issue is, if I apply[TypeConverter(typeof(WrapperConverter))] to my Wrapper<T> class, the XAML parser doesn't find the constructor for WrapperConverter (since it has no default constructor) and hence throws a XamlParseException.

Most likely solution to me

Now if I implement a TypeDescriptionProvider and a CustomTypeDescriptor :

public class WrapperTypeDescriptor : CustomTypeDescriptor
{
    private readonly Type objectType;

    public WrapperTypeDescriptor(Type objectType)
    {
        this.objectType = objectType;
    }

    public override TypeConverter GetConverter()
    {
        Type wrappedType = objectType.GenericTypeArguments[0];
        return new WrapperConverter(wrappedType);
    }
}

public class WrapperTypeDescriptionProvider : TypeDescriptionProvider
{
    public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance)
    {
        return new WrapperTypeDescriptor(objectType);
    }
}

I can control the WrapperConverter's instantiation and use my WrapperConverter's parameterized constructor and convert strings to Wrapper<T> instances by applying [TypeDescriptionProvider(typeof(WrapperTypeDescriptionProvider))] to my Wrapper<T> class :

Console.WriteLine(TypeDescriptor.GetConverter(typeof(Wrapper<int>)).ConvertFromString("18"));

will output :

System.Int32 : 18

The only problem with this solution is that WPF's xaml parser doesn't seem to look for a TypeDescriptionProviderAttribute but only a TypeConverterAttribute.

@nalka0 nalka0 changed the title Support for TypeDescriptionProvider when resolving the TypeConverter used to parse xaml files Support for TypeDescriptionProvider when resolving the TypeConverter used while parsing xaml files May 11, 2021
@ryalanms
Copy link
Member

Thanks, @nalka0. Please don't assign bugs directly to WPF developers. They are assigned based on priority.

@nalka0
Copy link
Author

nalka0 commented May 26, 2021

Thanks, @nalka0. Please don't assign bugs directly to WPF developers. They are assigned based on priority.

@ryalanms SamBent is the default assignee when doing "new issue" => "feature request", and the only way I can change this is removing the assignees=SamBent part of the URL, I think there's a setting that you'd like to change for the feature request button?

@ryalanms ryalanms added this to the Future milestone Aug 27, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants