Support for TypeDescriptionProvider when resolving the TypeConverter used while parsing xaml files
- Dominant language
- C#
- Stars
- 7.7k
- Forks
- 1.3k
- Avg merge
- 1d 11h
- Merged PRs (30d)
- 61
Description
**Issue to fix**
Considering the following class :
```cs
public class Wrapper
{
public T Wrapped { get; set; }
public override string ToString()
{
return $"{Wrapped.GetType()} : {Wrapped}";
}
}
```
If I have an object with a property of type `Wrapper` and want to use it in XAML like `MyProperty="SomeValue"` a TypeConverter is required.
Here, the TypeConverter implementation would look like :
```cs
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();
retType.GetProperty(nameof(Wrapper.Wrapped)).SetValue(ret, conversionResult); // ret.Wrapped = conversionResult;
return ret;
}
}
```
The issue is, if I apply`[TypeConverter(typeof(WrapperConverter))]` to my `Wrapper` 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 :
```cs
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` instances by applying `[TypeDescriptionProvider(typeof(WrapperTypeDescriptionProvider))]` to my `Wrapper` class :
```cs
Console.WriteLine(TypeDescriptor.GetConverter(typeof(Wrapper)).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.
Contributor guide
Assessment
This issue has not been assessed yet.