2009-07-22 50 views
3

我有一個應用程序,我希望能夠在運行時編輯任何類型(字體,顏色,點等)並使用任何類型。淨默認類型編輯器。 (例如,字體/顏色選擇器)。如何在表單中使用屬性網格來編輯任何類型

與其重新發明輪子,我決定使用屬性網格控件。

如果我將一個字體的對象傳遞給網格,它將單獨列出所有的字段,但不能打開字體選擇器。

因此,我創建這個通用包裝類:

Private Class Wrapper(Of T) 
    Private _Value As T 
    Public Property Value() As T 
     Get 
      Return Me._Value 
     End Get 
     Set(ByVal value As T) 
      Me._Value = value 
     End Set 
    End Property 

    Public Sub New(ByVal Value As T) 
     Me._Value = Value 
    End Sub 
End Class 

代替傳遞一個字體對象的網格,我通過包裝的一個實例。然後屬性網格表現得如我所願。

這工作,但問題是,對象可以是任何類型的,我不能編寫類似 -

Dim MyWrapper = New Wrapper(of T)(myObject). 

基本上,我掌握的信息是該類型的裝配合格的名稱和一個字符串對象的表示。然後我用一個類型轉換器來創建對象:

Dim ID As String = "System.Drawing.Font, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" 
Dim PropertyValue As String = "Arial, 12px, style=Bold, Strikeout" 
Dim T As Type = System.Type.GetType(ID) 
Dim tc As TypeConverter = TypeDescriptor.GetConverter(T) 
Dim o As Object = tc.ConvertFromString(PropertyValue) 

如果我通過對象屬性網格,它的工作原理,但如果我通過包裝的一個實例,這是行不通的。

我已經通過使用reflection.Emit在運行中創建所需類型的非通用包裝來解決問題,但我懷疑這是過度殺死。

任何想法?

ETA:

我有什麼做的,如果我用的是網編輯財產的問題,說了字體,這是不是已經定義。

如果定義:

Dim f as Font = Nothing 

,並傳遞到包裝器,如所預期與(無),並用...一個按鈕來選擇字體屬性網格顯示。

我的問題是如何在運行時如何處理Dim myObject As'Type'= Nothing。

我找不到辦法做到這一點,但幸運的是與包裝和我的類型,這不是一個問題。 我改變普拉迪普的代碼(看答案)到:

Dim genericType As Type = GetType(Wrapper(Of)) 
Dim specificType As Type = genericType.MakeGenericType(T) 
Dim ci As ConstructorInfo = specificType.GetConstructor(New Type() {T}) 
Dim wrappedObject As Object = ci.Invoke(New Object() {Nothing}) 
Me.PropertyGrid1.SelectedObject = wrappedObject 

問題解決了!

回答

3

我認爲這應該工作。我在C#中進行了測試,並使用了轉換器在VB.net

獲得代碼這是在C#代碼

Type generic = typeof(Wrapper<>); 
Type specific = generic.MakeGenericType(o.GetType()); 
ConstructorInfo ci = specific.GetConstructor(new Type[] { o.GetType() }); 
object o1 = ci.Invoke(new object[] { o }); 
propertyGrid1.SelectedObject = o1; 

VB.NET

Dim generic As Type = Type.GetType(Wrapper<>) 
Dim specific As Type = generic.MakeGenericType(o.GetType()) 
Dim ci As ConstructorInfo = specific.GetConstructor(New Type() {o.GetType() }) 
Dim o1 As Object = ci.Invoke(New Object(){ o }) 
propertyGrid1.SelectedObject = o1 
+0

感謝隊友,這是現貨上。我知道我曾經使用過這樣的東西,但我總是忘記你可以引用一個沒有子類型的泛型類型。 我的28行發射代碼現在替換爲4 :-) 只是稍作修改,第一行被錯誤地轉換,它應該是:Dim generic As As Type = GetType(Wrapper(Of)) – Jules 2009-07-22 09:27:57

相關問題