在 .Designer 中缩写序列化
Abbreviate serialization in .Designer
我有一个 属性 类型为 Foo
的自定义控件。我为此 class 创建了一个 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 的答案。
Designer (VS) 将按照自己的意愿编写它,这在很大程度上取决于您的 Foo
类型是如何构建的以及它继承自什么。但总的来说,您可以提供一个 TypeConverter
并且至少可以使用构造函数参数获得更短的形式。
这是通过在 CanConvertTo
和 ConvertTo
中回复 InstanceDescriptor
来完成的:
<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
Hidden
的 DesignerSerializationVisibility
属性值告诉 VS 不要去序列化那个 属性。目的是通过重载的构造函数来处理它。类型转换器:
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
上面的拼写是为了清楚起见,但您可以使用 shorthand:
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)
请注意,尾随 Boolean
参数指示 VS 是否应查找更多属性。 Boolean
和 属性 上的 DesignerSerializationVisibility
值的组合将决定是 VS 序列化值还是您的 TC 处理它。任何值都希望保留,应该由您的 TypeConverter 处理或设置为 .Visible
.
最后,由于没有关于自定义控件或真实 Foo
类型的信息,所以很难知道如何应用一些细节(什么是可序列化的等)。
摘自 Enhanced CollectionEditor Framework,涵盖了简单的 TC 和设计器序列化。
就我个人而言,如果 VS 通常会做的任何事情都会起作用,那么似乎需要做很多额外的工作。
我有一个 属性 类型为 Foo
的自定义控件。我为此 class 创建了一个 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 的答案。
Designer (VS) 将按照自己的意愿编写它,这在很大程度上取决于您的 Foo
类型是如何构建的以及它继承自什么。但总的来说,您可以提供一个 TypeConverter
并且至少可以使用构造函数参数获得更短的形式。
这是通过在 CanConvertTo
和 ConvertTo
中回复 InstanceDescriptor
来完成的:
<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
Hidden
的 DesignerSerializationVisibility
属性值告诉 VS 不要去序列化那个 属性。目的是通过重载的构造函数来处理它。类型转换器:
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
上面的拼写是为了清楚起见,但您可以使用 shorthand:
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)
请注意,尾随 Boolean
参数指示 VS 是否应查找更多属性。 Boolean
和 属性 上的 DesignerSerializationVisibility
值的组合将决定是 VS 序列化值还是您的 TC 处理它。任何值都希望保留,应该由您的 TypeConverter 处理或设置为 .Visible
.
最后,由于没有关于自定义控件或真实 Foo
类型的信息,所以很难知道如何应用一些细节(什么是可序列化的等)。
摘自 Enhanced CollectionEditor Framework,涵盖了简单的 TC 和设计器序列化。
就我个人而言,如果 VS 通常会做的任何事情都会起作用,那么似乎需要做很多额外的工作。