Vb.Net设置用户控件的属性

时间:2014-06-16 10:25:03

标签: vb.net properties

我有一个自定义用户控件&我期待从设计师那里设置一些属性。这些属性将来自一个结构。这是当前的代码

Private fooList As Foo_structure

    Public Structure Foo_structure
        Public Property a As Integer
        Public Property b As Integer
        Public Property c As Extras
    End Structure

    Public Structure Extras
        Public Property precision As Integer
        Public Property light As String
    End Structure

    Public Property foo As Foo_structure
        Get
            Return fooList
        End Get
        Set(ByVal value As Foo_structure)
            fooList = value
        End Set
    End Property

我需要能够从设计器属性面板设置Foo_structure的属性,如下图所示。

example

1 个答案:

答案 0 :(得分:4)

你需要一个TypeConverter来将foo折叠成一个字符串;并从它转换回来。嵌套类型意味着您需要为Extras编写另一个。您可能需要使用一些属性来处理设计器持久性。

首先,我认为您需要将至少Foo_structure更改为Class,否则无法将代码添加到实例Extras(也无法创建Foo实例)。这应该让你开始(改变一些名字):

' Foo converted to Class:
<TypeConverter("FooItemConverter")>
Public Class FooBar
    <DefaultValue(0)>
    <DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)>
    Public Property Foo As Integer

    <DefaultValue(0)>
    <DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)>
    Public Property Bar As Integer

   <EditorBrowsable(EditorBrowsableState.Always)>
   <NotifyParentProperty(True)>
   <DesignerSerializationVisibility(DesignerSerializationVisibility.Content)>
    Public Property Ex As Extras

    Public Sub New(a1 As Integer, b2 As Integer)
        Foo = a1
        Bar = b2
        Ex = New Extras    ' do not want NOTHING flying about
    End Sub

End Class

DefaultValue并没有按照您的想法行事。它告诉IDE在当前值不等于Default时序列化属性的值。 DesignerSerializationVisibility告诉VS保存属性的值。 Foo和Bar都需要这些。

Ex / Extra不同。 NotifyParentProperty允许在Extra属性值发生更改时通知FooBar,以便更新IDE窗口,内部&#34; DirtyFlag&#34;设置等; DesignerSerializationVisibility.Content告诉VS我们知道我们不能将Ex保存为值,因此保存内容。

然后是FooItemConverter。这将是在Props窗口中显示所需字符串的东西,并从该字符串创建一个Foo项:

Friend Class FooItemConverter
   Inherits ExpandableObjectConverter

   ' tells the IDE what conversions it can handle:
    Public Overrides Function CanConvertTo(context As ITypeDescriptorContext,
                                              destType As Type) As Boolean
        If destType = GetType(String) Then
            ' Yes I Can
            Return True
        End If
        ' Probably have to also say YES to an InstanceDescriptor 
        Return MyBase.CanConvertTo(context, destType)
    End Function

之后使用ConvertTo函数将foo转换为字符串。像这样:

Public Overrides Function ConvertTo(context As ITypeDescriptorContext,
                                culture As Globalization.CultureInfo,
                                value As Object, destType As Type) As Object
    If destType = GetType(String) Then

        Dim f As FooBar = CType(value, FooBar)
        Return String.Format("{0}, {1}, {2}", 
                f.foo.ToString, 
                f.bar.ToString, 
                f.Ex.ToString)

       ' outputs: X, Y, <ex>
       ' where Ex is what we use in the ExtraItemConverter

    End If

    Return MyBase.ConvertTo(context, destType)
End Function

如果ExtraItemConverter.ConvertTo使用的格式为"({0} / {1})",则控件内容将显示为:F, B, (P / L),其中F = Foo,B = Bar等。

要使其工作,您需要4个程序:CanConvertTo,ConvertTo,CanConvertFrom,ConvertFrom都响应字符串。您可能只能使用<DefaultValue>属性来保持持久性。

FooItemConverter.ConvertFrom必须知道如何从该字符串创建对象。通常情况下,这样做:

' parse the string you made and create a Foo
Dim els As String() = str.Split(","c)
Return New myFoo(Convert.ToInt32(els(0)), Convert.ToInt32(els(1)))

请注意,第3个元素会被忽略,因为它实际上是ExtraItemConverter要处理的。那个转换器非常相似。

因此,您首先必须决定是否依附于结构或使用类(另一个专业类是您发现的99.999%的示例将基于类)。 These guysTypeConverters了解很多。