在设计时,从自定义UITypeEditor中使用组件控件

时间:2017-05-08 16:20:57

标签: uitypeeditor

虽然有许多线程处理类似的问题,但我找不到任何涵盖这种情况的线索。

我有一个引用类库的主应用程序。在类库中是一个带有属性的控件,该属性必须使用主应用程序中可用表单的下拉列表中的表单名称填充 - 而不是类库。

我发现,在UITypeEditor代码中,

Control owner = context.Instance as Control;

给出了对需要属性值的控件的引用。但是获得对正确程序集的引用(主应用程序,而不是控件所在的库)以便我可以在下拉列表中列出可用的表单名称已经证明是困难的。

owner.GetType().Assembly.ToString() - 给我类库名称,而不是主应用程序

Assembly.GetExecutingAssembly().ToString() ---给我类库名称

Assembly.GetCallingAssembly().ToString() ---给我System.Windows.Forms

我找不到路由来获取我正在放置控件的表单的组件,该控件具有需要该程序集的自定义编辑器的属性。

1 个答案:

答案 0 :(得分:0)

我意识到这是一个老问题,但如果理解编写基本设计器代码所采用的机制,就很容易回答。我推荐阅读三篇文章,以获得有关该主题的工作知识。

  1. 使用丰富的设计时功能构建Windows窗体控件和组件; MSDN Magazine, April 2003
  2. 使用丰富的设计时功能构建Windows窗体控件和组件,第2部分; MSDN Magazine, May 2003
  3. 通过使用.NET构建自定义窗体设计器来定制应用程序; MSDN Magazine, December 2004
  4. 注意:以上链接是编译的HTML帮助文件。请记住使用文件的属性对话框取消阻止内容。

    enter image description here

    要获得对Assembly的{​​{1}}的引用,Form在设计图面上操作Control,您需要获取对IDesignerHost服务的引用来自IServiceProvider实例"提供商"传递EditValue方法。 IDesignerHost公开属性RootComponentClassName,它将是基本组件类的完全限定名,在本例中是包含的形式。使用此名称,您可以使用Type方法获取IDesignerHost.GetType实例。请注意,如果项目尚未构建" 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