This message was discovered on microsoft.public.dotnet.framework.clr.
Responses highlighted in red are from those people who are likely to be able to contribute good, authoratitive information to this discussion. They include Microsoft employees, MVP's and others who IMHO contribute well to these kinds of discussions.
| Jürgen Weiss |
Hi folks, I have a problem with obtaining the TypeConverter for a Control which is defined in an external assembly. The problem is that TypeDescriptor.GetConverter() fails to retrieve the proper converter instance, whereas creating the converter manually by inspecting the TypeConverter attribute of the property and instantiating the instance through its construcor works fine.
To make it even weirder the problem only occurs if the code is used in an Active X Control run from internet explorer - if the control is instantiated from a managed windows application both approaches lead to the same result.
Here is my code: -- TestControl.cs, part of a ControlLibrary using System; using System.Collections; using System.ComponentModel; using System.Windows.Forms;
namespace TypeRes { public class TestControl : System.Windows.Forms.Label { public MyPropertyType myProperty = new MyPropertyType(); }
[TypeConverter(typeof(MyTypeConverter))] public class MyPropertyType { public string value; }
public class MyTypeConverter : TypeConverter { } }
-- ActiveXCtrl.cs, part of another Control Library using System; using System.Runtime.InteropServices; using System.Windows.Forms; using System.ComponentModel; using System.Reflection;
namespace TypeRes { [Guid("7785814e-401b-4901-a5e6-247e08928582")] [ProgId("TypeRes.Test.ActiveXCtrl")] public class ActiveXCtrl : System.Windows.Forms.UserControl { public ActiveXCtrl() { TypeRes.TestControl control = new TypeRes.TestControl(); Type propertyType = control.myProperty.GetType();
// use TypeDescriptor class to get hold of the converter object converter1 = TypeDescriptor.GetConverter(propertyType);
// do it manually by examining the TypeConverter attribute of the property type object[] attr = propertyType.GetCustomAttributes(typeof(TypeConverterAttribute), true); TypeConverterAttribute ta = attr[0] as TypeConverterAttribute;
Type converterType = Type.GetType(ta.ConverterTypeName); ConstructorInfo[] ci = converterType.GetConstructors();
object converter2 = ci[0].Invoke(new object []{});;
if (converter1.GetType() != converter2.GetType()) MessageBox.Show( "!!! The converter types do not match !!!\n\n" + converter1.GetType().ToString() + " != " + converter2.GetType().ToString()); else MessageBox.Show( "Both converters are of type " + converter1.GetType().ToString()); } } }
-- TestPage.htm HTML> <BODY> <OBJECT classid="clsid:7785814e-401b-4901-a5e6-247e08928582"> </OBJECT> </BODY> </HTML>
-- TestApp.cs, Windows Application using System;
namespace TypeRes { class TestApp { [STAThread] static void Main(string[] args) { TypeRes.ActiveXCtrl comCtrl = new TypeRes.ActiveXCtrl(); } } }
Now, if I run the test application, the message box shows "Both converters are of type TypeRes.MyTypeConverter" If I open TestPage.htm, the message is "!!! The converter types do not match !!! System.ComponentModel.TypeConverter != TypeRes.MyTypeConverter"
???? Obviously TypeDescriptor.GetConverter is not able to instantiate the proper type converter and returns a default implementation.
With the help of the wonderful .Net Reflector tool and a bit of assembly debugging I found that TypeDescriptor.GetConverter calls the GetTypeFromName method of the internal class System.ComponentModel.TypeDescriptor.ComponentEntry which in turn calls Type.GetType(typeName) where typeName is the fully qualified name of the MyTypeConverter type. The strange thing is that Type.GetType returns null if called from the System.dll assembly but retrieves a proper value if called from application code!!!
I would appreciate very much if someone of the CLR experts could shed some light on this issue. Thanks for your help! - Jürgen
|
|
| |
| |
| Mike Harsh[MSFT] (VIP) |
This looks like a bug in the GetCOnverter method. Please use the MSDN product feedback center to report this bug. Using the MSDN feedback center will allow you to track this bug through its lifespan and will also allow others to vote for it.
http://lab.msdn.microsoft.com/ProductFeedback
Thanks - mike -------------------- [Original message clipped]
__
This posting is provided "AS IS" with no warranties and confers no rights.
|
|
| |
| |
| Jürgen Weiss |
Thanks a lot for the prompt feedback. I've submitted the bug report (in case someone is interested: the bug id is FDBK14969)
"Mike Harsh[MSFT]" <Click here to reveal e-mail address> schrieb im Newsbeitrag news:Click here to reveal e-mail address... [Original message clipped]
|
|
| |
| |
| Jürgen Weiss |
Today I found a workaround for this problem: registering a handler for the AssemblyResolve event seems to help. See the excerpt from the problem report: Workaround Description: The problem seems to go away if one registers a handler for the AssemblyResolve event of the current AppDomain. The handler simply searches the loaded assemblies of the calling domain.
Two questions remain: - Why is the behavior depending on whether the control runs in IE - Why is AssemblyResolve invoked for an assembly which has already been resolved (loaded)
Workaround Steps: Add following code to ActiveXCtrl class:
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; }
public ActiveXCtrl() { AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
TypeRes.TestControl control = new TypeRes.TestControl(); Type propertyType = control.myProperty.GetType();
// use TypeDescriptor class to get hold of the converter object converter1 = TypeDescriptor.GetConverter(propertyType);
"Jürgen Weiss" <Click here to reveal e-mail address> schrieb im Newsbeitrag news:cheqrv$o71$Click here to reveal e-mail address... [Original message clipped]
|
|
| |
|
|
|
|
|
|
|