我意识到这是一个老问题,但如果了解编写基本设计器代码所采用的机制,则很容易回答。我建议您阅读三篇文章,以获取有关该主题的实用知识。
- 构建具有丰富设计时功能的 Windows 窗体控件和组件; MSDN Magazine, April 2003
- 构建具有丰富设计时功能的 Windows 窗体控件和组件,第 2 部分; MSDN Magazine, May 2003
- 通过使用 .NET 构建自定义表单设计器来定制您的应用程序; MSDN Magazine, December 2004
注意:以上链接指向已编译的 HTML 帮助文件。请记住使用文件的属性对话框取消阻止内容。
要获得对包含Form 的Assembly 的引用,并且在设计图面上对Control 进行操作,您需要从IDesignerHost 服务的引用获得IServiceProvider 实例“提供程序”的引用" 即通过 EditValue 方法。 IDesignerHost 公开属性RootComponentClassName,它将是基组件类的完全限定名称,在这种情况下是包含表单。使用此名称,您可以使用IDesignerHost.GetType 方法获取Type 实例。请注意,如果在将表单添加到项目后尚未“构建”项目,GetType 可能会返回空值。
UITypeEditor 的 C# 示例代码段
public override object EditValue(System.ComponentModel.ITypeDescriptorContext context, IServiceProvider provider, object value)
{
IDesignerHost host = provider.GetService(typeof(IDesignerHost)) as IDesignerHost;
string typName = host.RootComponentClassName;
Type typ = host.GetType(typName);
Assembly asm = null;
if (typ == null)
{
MessageBox.Show("Please build project before attempting to set this property");
return base.EditValue(context, provider, value);
}
else
{
asm = typ.Assembly;
}
// ... remaining code
return base.EditValue(context, provider, value);
}
用于 UITypeEditor 的 VB 示例代码段
Public Overrides Function EditValue(context As ITypeDescriptorContext, provider As IServiceProvider, value As Object) As Object
Dim host As IDesignerHost = TryCast(provider.GetService(GetType(IDesignerHost)), IDesignerHost)
Dim typName As String = host.RootComponentClassName
Dim typ As Type = host.GetType(typName)
Dim asm As Assembly
If typ Is Nothing Then
MessageBox.Show("Please build project before attempting to set this property")
Return MyBase.EditValue(context, provider, value)
Else
asm = typ.Assembly
End If
' ... remaining code
Return MyBase.EditValue(context, provider, value)
End Function