如何使用属性网格的形式编辑任何类型(How to use the property grid in

2019-07-30 14:20发布

我有一个应用程序,我希望能够编辑在运行时的任何类型(字体,颜色,点等)和使用任何的.Net默认类型的编辑。 (例如,字体/颜色选择器)。

而不是重新发明轮子,我决定使用属性网格控制。

如果我通过的对象,说的字体,到网格,它列出了所有的领域分开,不带选项打开字体选择器。

因此,我创造了这个通用的包装类:

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的,以动态创建所需类型的非通用包装解决了这个问题,但我怀疑这是超必杀。

有任何想法吗?

AND:

我有什么做的,如果我用的是网编辑财产的问题,说了字体,这是不是已经定义。

如果定义:

Dim f as Font = Nothing

,并传递到包装器,如所预期与(无),并用...一个按钮来选择字体属性网格显示。

我的问题是怎么做的点心myObject的作为“类型” =无等价,在运行时。

我无法找到一个方法来做到这一点,但幸运的是,与包装物和我喜欢的类型,这不是一个问题。 我改变普拉迪普的代码(看答案)到:

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

问题解决了!

Answer 1:

我想,这应该工作。 我在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


文章来源: How to use the property grid in a form to edit any Type