缩写系列化.Designer缩写、Designer

2023-09-06 10:19:59 作者:愿得伊人心

我有一个类型的属性自定义控件。我创建了一个 UITypeEditor的这个类。

I have a custom control with a property of type Foo. I created an UITypeEditor for this class.

这工作得很好,结果在设计code这样的:

This works well and results in designer code like:

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"

的东西属性类型键,你可以看到设计师创建了一个新的对象 Foo1 明确地。

The Something property is of type Foo and as you can see the designer creates a new object Foo1 explicitely.

我的问题是:我可以告诉设计师用来而创建Foo对象内联,如关键字:

My question is: Can I tell the designer to rather create the foo object inline using the With keyword like:

'
'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"

我想是为了避免在设计文件中的混乱时,更复杂的类型将被创建。

I would like this to avoid clutter in the designer file when more complex types are to be created.

答案在两个C#或VB.NET是多少AP preciated。

Answers in both C# or VB.NET are much appreciated.

推荐答案

在设计器(VS)会如何想将它写出来,很大取决于你的类型是建立和它的继承。但在一般情况下,你可以提供一个类型转换器和至少使用构造PARAMS获得一个短一点的形式。

The Designer (VS) is going to write it out how it wants and a great deal depends on how your Foo type is built and what it inherits from. But in general, you can provide a TypeConverter and at least get a bit shorter form using constructor params.

这是由 CanConvertTo 响应 InstanceDescriptor 的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 属性隐藏的值告诉VS不要打扰序列化的属性。其目的是通过重载的构造函数来处理它。该类型转换器:

The DesignerSerializationVisibility attribute value of Hidden tells VS not to bother serializing that property. The intention is to handle it via the overloaded constructor. The TypeConverter:

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

以上是拼写出来的清晰度,但您可以使用简写:

The above is spelled out for clarity, but you can use shorthand:

Return New InstanceDescriptor(GetType(Foo). _
                              GetConstructor(New Type() _
       {GetType(String),
       GetType(Integer)}),
       New Object() {f.Name, f.Value}, False)

设计者code结果仍然是一个明确的临时对象,但有点更紧凑,而且任何的等的属性时,将普碳钢由一个设定之一:

The designer code result will still be an explicit temp object, but a bit more compact, and any other properties would stell be set one by one:

Dim Foo1 As Prj.Foo = New Prj.Foo("Ziggy", 43)

请注意,尾随布尔参数表示VS是否应该寻找更多的属性。对这种组合布尔并在属性 DesignerSerializationVisibility 值将决定是否VS序列化值,或您的TC处理它。任何值都希望坚持,要么被你的TypeConverter或处理设置为。可见

Note that the trailing Boolean parameter indicates whether VS should look for more properties. The combination of that Boolean and the DesignerSerializationVisibility value on a property will determine if VS serializes the values or your TC handles it. Any value would wish to persist, should either be handled by your TypeConverter or be set to .Visible.

最后,对自定义控制或实际没有资料键入它是很难知道如何应用的一些细节(什么是序列化等)。

Finally with no info on the custom control or the real Foo type it is hard to know how to apply some of the details (what's serializable etc).

从增强CollectionEditor框架摘录涵盖简单的热带气旋和设计师的系列化。

Excerpted from Enhanced CollectionEditor Framework which covers simple TCs and designer serialization.

就个人而言,这似乎是一个很大的提供额外的工作,无论VS通常会做的工作。

Personally, it seems like a lot of extra work provided whatever VS will normally do will work.