我有一个自定义用户控件,我希望从设计器中设置它的一些属性。这些属性将来自结构。这是当前的代码
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
Run Code Online (Sandbox Code Playgroud)
我需要能够从设计器属性面板设置 Foo_struct 的属性,如下图所示。

您将需要 aTypeConverter将 foo 折叠成字符串;并从中转换回来。嵌套的 Type 意味着您需要为 编写另一个类型Extras。您可能需要使用一些属性来处理设计器持久性。
首先,我认为您至少需要将 Foo_struct 更改为 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
Run Code Online (Sandbox Code Playgroud)
DefaultValue并没有做你可能认为它会做的事情。当当前值不等于默认值时,它告诉 IDE 序列化属性的值。 DesignerSerializationVisibility告诉 VS 保存属性的值。Foo 和 Bar 都需要这些。
额外/额外是不同的。 NotifyParentProperty允许 FooBar 在 Extra 属性值发生更改时收到通知,以便更新 IDE 窗口、设置内部“DirtyFlag”等;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
Run Code Online (Sandbox Code Playgroud)
之后,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
Run Code Online (Sandbox Code Playgroud)
如果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)))
Run Code Online (Sandbox Code Playgroud)
请注意,第三个元素被忽略,因为它实际上是要ExtraItemConverter处理的。该转换器非常相似。
因此,您首先必须决定是坚持结构还是使用类(类的另一个优点是您找到的 99.999% 的示例都是基于类的)。这些家伙知道很多TypeConverters。
| 归档时间: |
|
| 查看次数: |
3088 次 |
| 最近记录: |