2017-05-08 52 views
0

雖然有很多處理類似問題的線程,但我找不到涵蓋這種情況的任何線程。在設計時從一個自定義的UITypeEditor獲取組件的控件,在設計時使用

我有一個引用類庫的主應用程序。在類庫中是一個具有屬性的控件,必須使用主應用程序中可用表單的下拉列表填充表單名稱 - 而不是類庫。

我發現,在UITypeEditor的代碼裏面,

Control owner = context.Instance as Control; 

給我需要哪些屬性值的控制提供參考。但是要獲得適當程序集(主應用程序,而不是控件所在的庫)的引用,以便我可以在下拉列表中列出可用的表單名稱,這很困難。

owner.GetType().Assembly.ToString() - 給我的類庫名稱,而不是主要的應用程序

Assembly.GetExecutingAssembly().ToString() ---給我的類庫名

Assembly.GetCallingAssembly().ToString() ---給我System.Windows.Forms的

我找不到能夠獲得表單的彙編的路由,我將該表單的控件與具有需要該彙編的自定義編輯器的屬性相關聯。

回答

0

我意識到這是一個老問題,但如果理解編寫基本設計器代碼時使用的機制,則很容易回答。我推薦閱讀三篇文章以獲取有關該主題的工作知識。

  1. 構建Windows窗體控件和具有豐富設計時功能的組件; MSDN Magazine, April 2003
  2. 構建Windows窗體控件和具有豐富設計時功能的組件,第2部分; MSDN Magazine, May 2003
  3. 通過使用.NET構建自定義窗體設計器來定製您的應用程序; MSDN Magazine, December 2004

注意:上述鏈接是編譯好的HTML幫助文件。請記住使用文件的屬性對話框取消阻止內容。

enter image description here

爲了獲得對Assembly參考包含FormControl設計表面上被操縱的,你需要獲得從傳遞的IServiceProvider實例「供應商」的IDesignerHost服務的引用方法EditValue。 IDesignerHost公開屬性RootComponentClassName,該屬性將是基本組件類的完全限定名稱,在這種情況下,它是包含表單。使用該名稱,您可以使用IDesignerHost.GetType方法獲得Type實例。請注意,GetType可能會返回空值,如果該項目自從將該窗體添加到該項目以來尚未「構建」。

C#實施例摘錄對於UITypeEditor的

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); 
    } 

VB例摘錄對於UITypeEditor的

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