using System;
using System.ComponentModel;
using System.Globalization;
using System.Reflection;
using System.Xaml;
namespace Example
{
public class MyConverter : TypeConverter
{
public override object ConvertFrom( ITypeDescriptorContext context , CultureInfo culture , object value )
{
Type type1 = ( (dynamic) value ).GetType();
Type type2 = typeof( Foo<> ).MakeGenericType( type1 );
object instance = Activator.CreateInstance( type2 );
PropertyInfo prp = type2.GetProperty( nameof( Foo<byte>.Value ) );
prp.SetValue( instance , Convert.ChangeType( value , type1 ) );
return instance;
}
}
public class Foo<T>
{
public T Value { get; set; }
}
public class Bar
{
public int SomeNumber { get; set; }
}
public class MyClass
{
[TypeConverter( typeof( MyConverter ) )]
public Foo<Bar> MyProperty { get; set; }
public void ConvertImplicit()
{
string xml = "<MyClass xmlns=\"http://Example\"> <MyClass.MyProperty> <Bar SomeNumber=\"5\" /> </MyClass.MyProperty> </MyClass>";
MyClass myClass = XamlServices.Parse( xml ) as MyClass;
}
public void ConvertExplicit()
{
MyConverter myConverter = new MyConverter();
Bar bar = new Bar() { SomeNumber = 5 };
Foo<Bar> target = myConverter.ConvertFrom( null , null , bar ) as Foo<Bar>;
}
}
}
The shown TypeConverter works as expected when converting explicitly, demonstrated in ConvertExplicit. When the convertion is done implicitly, like so in ConvertImplicit an exception is thrown, which says that MyProperty can not be set.
The exception is thrown because there is no final cast done like in ConvertExplicit.
When using the TypeConverter for implicit convertions, e.g. when using XamlServices, there is no way to do the final cast.
How can I modify my TypeConverter to work like ConvertExplicit (without th final cast after the convertion)?
By the way: To run ConvertImplicit you need to add this to the AssemblyInfo.cs [assembly: XmlnsDefinition( "http://Example" , "Example" )]