I am trying to understand why the below code is not working as expected; the TypeDescriptor
is simply not picking up the custom converter from the attributes. I can only assume I have made an obvious mistake but I cannot see it.
-- edit -- this code seems to work when I run it in a console on its own, I'm actually calling a converter from within a much more complex application and from a different namespace.
-- edit -- alternatively any suggestions on how I can debug the TypeDescriptor so I can see what is going on and then I can probably answer this myself.
-- edit -- this problem is almost certainly related to pieces being in different assemblies.
-- edit -- It looks like this is not working because of some quirk of loading assemblies dynamically - this code is running under a plugin like architecture.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.ComponentModel;
namespace MyTest
{
public class TestTester
{
public static void Main(string[] args)
{
object v = TypeDescriptor.GetConverter(typeof(MyTest.Test)).ConvertFromInvariantString("Test");
}
}
public class TestConverter : TypeConverter
{
public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
{
return false;
}
public override bool CanConvertFrom(ITypeDescriptorContext context, System.Type sourceType)
{
if (sourceType == typeof(string) || base.CanConvertFrom(context, sourceType))
{
return true;
}
return base.CanConvertFrom(context, sourceType);
}
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
if (destinationType == typeof(Test) || base.CanConvertTo(destinationType))
{
return true;
}
return base.CanConvertTo(context, destinationType);
}
public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
{
if (value.GetType() == typeof(string))
{
Test t = new Test();
t.TestMember = value as string;
return t;
}
return base.ConvertFrom(context, culture, value);
}
public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
{
if (destinationType == typeof(string) && value.GetType() == typeof(Test))
{
return ((Test)value).TestMember;
}
return base.ConvertTo(context, culture, value, destinationType);
}
}
[TypeConverterAttribute(typeof(TestConverter))]
public struct Test
{
public string TestMember { get; set; }
}
}
I had this problem as well and a workaround to the problem is to subscribe to the AssemblyResolve event of the current application domain and resolve the assembly manually.
This is far from a good solution, but it seems to work. I have no idea why the framework behaves this way. I would myself really want to find a less hackish way of resolving this problem.
public void DoMagic()
{
// NOTE: After this, you can use your typeconverter.
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
}
private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
AppDomain domain = (AppDomain)sender;
foreach (Assembly asm in domain.GetAssemblies())
{
if (asm.FullName == args.Name)
{
return asm;
}
}
return null;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With