为什么这段code在 design-time工作正常但是run-time缺不能显示StringDictionaryEditor呢?
using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using System.Collections.Specialized;
namespace MySimpleControl
{
public class MyCtl : UserControl
{
private StringDictionary environmentVariables = new StringDictionary();
[
DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
Editor("System.Diagnostics.Design.StringDictionaryEditor, System.Design",
"System.Drawing.Design.UITypeEditor,System.Drawing")
]
public StringDictionary EnvironmentVariables
{
get {return this.environmentVariables;}
set
{
this.environmentVariables = value;
}
}
}
}
UPDATE: 问题出在”System.Diagnostics.Design.StringDictionaryEditor, System.Design”这个声明上,
.NET在通过字符串取得一个Type时要求输入Full Qualified Type Name(FQTN)
FQTN:包括
例如 WinForm中Form类的Type就是
System.Windows.Forms.Form, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, Custom=null
我们可以使用Type.GetType方法来取得对应的类型。
那为什么文档中告诉我们可以只写System.Design就可以了呢?答案时VS.NET IDE会帮我们补全。
在GetType过程中,CLR会尝试装载指定的assembly,当CLR无法装载某个assembly时(例如assembly找不到,或assembly 的Full Qualified Assembly Name 不完整)则会触发当前AppDomain的AssemblyResolve事件,VS.NET IDE正是使用了这个事件帮助我们解析并装载合适的Assembly,这样这个字符串就可以正常运行了。
当然现在我们就有了解决方法,自己处理AssemblyResolve事件。
private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
if (args.Name == "System.Design")
{
Assembly asm = Assembly.Load("System.Design, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
return asm;
}
if (args.Name == "System.Drawing")
{
Assembly asm = Assembly.Load("System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
return asm;
}
return null;
}