我有一个属性为Foo
的自定义控件。我为这个班级创建了一个UITypeEditor
。
这很有效,可以产生如下设计师代码:
Dim Foo1 As PropertySerialization.Foo = New PropertySerialization.Foo()
Me.FooControl1 = New PropertySerialization.FooControl()
Me.SuspendLayout()
'
'FooControl1
'
Me.FooControl1.Location = New System.Drawing.Point(35, 56)
Me.FooControl1.Name = "FooControl1"
Me.FooControl1.Size = New System.Drawing.Size(188, 136)
Foo1.A = 3
Foo1.B = "World"
Me.FooControl1.Something = Foo1
Me.FooControl1.TabIndex = 0
Me.FooControl1.Text = "FooControl1"
Something
属性的类型为Foo
,您可以看到设计器明确地创建了一个新对象Foo1
。
我的问题是:我可以告诉设计师使用With
关键字来内联创建foo对象,如:
'
'FooControl1
'
Me.FooControl1.Location = New System.Drawing.Point(35, 56)
Me.FooControl1.Name = "FooControl1"
Me.FooControl1.Size = New System.Drawing.Size(188, 136)
Me.FooControl1.Something = New Foo() With {.A = 3, .B = "World"}
Me.FooControl1.TabIndex = 0
Me.FooControl1.Text = "FooControl1"
我希望在创建更复杂的类型时避免设计器文件中的混乱。
非常感谢C#或VB.NET中的答案。
答案 0 :(得分:1)
Designer(VS)将把它想象出来并且很大程度上取决于你的Foo
类型的构建方式以及它的继承方式。但一般来说,你可以使用构造函数参数提供TypeConverter
并至少缩短形式。
这是通过回复InstanceDescriptor
和CanConvertTo
中的ConvertTo
来完成的:
<Serializable>
<TypeConverter(GetType(FooConverter))>
Public Class Foo
Inherits ??????
<DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)>
Public Property Name As String
<DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)>
Public Property Value As Integer
Public Sub New(newName As String, v As Integer)
Name = newName
Value = v
End Sub
' simple constructor
Public Sub New()
Name = "New Foo"
Value = 0
End Sub
End Sub
DesignerSerializationVisibility
的{{1}}属性值告诉VS不要打扰序列化该属性。目的是通过重载的构造函数来处理它。 TypeConverter:
Hidden
为清楚起见,上述内容已明确说明,但您可以使用简写:
Friend Class FooConverter
Inherits TypeConverter
' designer serialization will check to see if
' there is a converter available
Public Overrides Function CanConvertTo(context As ITypeDescriptorContext,
destType As Type) As Boolean
If destType = GetType(InstanceDescriptor) Then
' Yes I Can!
Return True
End If
Return MyBase.CanConvertTo(context, destType)
End Function
Public Overrides Function ConvertTo(context As ITypeDescriptorContext,
info As CultureInfo, value As Object,
destType As Type) As Object
If destType = GetType(InstanceDescriptor) Then
Dim f As Foo = CType(value, Foo)
' prepare a constructor info
Dim ctor As Reflection.ConstructorInfo
' the ctor wanted, is the one which takes a string, and an Integer
ctor = GetType(Foo).GetConstructor(New Type() _
{GetType(String), GetType(Integer)})
' return Instance Descriptor built from ctor info and
' an array of the current values for the ctor
Return New InstanceDescriptor(ctor,
New Object() {f.Name, f.Value}, False)
End If
Return MyBase.ConvertTo(context, info, value, destType)
End Function
End Class
设计器代码结果仍然是一个显式的临时对象,但更紧凑,任何其他属性都将被逐个设置:
Return New InstanceDescriptor(GetType(Foo). _
GetConstructor(New Type() _
{GetType(String),
GetType(Integer)}),
New Object() {f.Name, f.Value}, False)
请注意,尾随Dim Foo1 As Prj.Foo = New Prj.Foo("Ziggy", 43)
参数指示VS是否应查找更多属性。属性上Boolean
和Boolean
值的组合将确定VS序列化值还是TC处理它。任何值都希望保留,应由TypeConverter处理或设置为DesignerSerializationVisibility
。
最后,由于没有关于自定义控件或真实.Visible
类型的信息,因此很难知道如何应用某些细节(可序列化等)。
摘自Enhanced CollectionEditor Framework,内容涵盖简单的TC和设计师序列化。
就个人而言,无论VS通常会做什么都可以提供很多额外的工作。