dotnet / dotnet/wpf

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

Open
#4,503 2 comments 1 reaction 0 assignees View on GitHub
Feature Request
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.