与持续的集合,引用了内部属性,在设计时的WinForms问题,.NET [英] Problem with persisting a collection, that references an internal property, at design time in winforms, .net
问题描述
(我已经回答了下面一个黑客攻击的问题,我相当有信心的,除非MS改变codeDOM串行设计code的方式。)
(I've answered the question below with a hack. I'm fairly confident in it unless MS change the way that codedom serializers the designer code.)
ETA2:
我已经计算出到底是怎么回事。我不知道为什么有时会工作,而不是别人。它归结为是我给的内部属性和收集的名称。
I've worked out what is going on. I wondered why sometimes it would work and not others. It boils down to the name that I give to the internal property and the collection.
如果我重新命名的属性'不舒服'到'跆拳道',它会正确地序列化,因为跆拳道是按字母顺序,集合的名称后 - 。InternalAnger
If I rename the property 'Annoyance' to 'WTF', it will serialize correctly because 'WTF' is, alphabetically, after the name of the collection - 'InternalAnger'.
它看起来像串行器创建对象按字母顺序排列的情况下,需要我的内部属性是由它来创建集合时创建的。
It looks like the serializer is creating instances of objects alphabetically and needs my internal property to be created by the time it comes to create the collection.
我可以重命名解决这个问题,但这是一个黑客,我担心写一个自定义序列化是一项艰巨的任务 - 这是我以前从来没有做过
I can fix this with a rename, but that's a hack and I fear that writing a custom serializer is a big job - which I've never done before.
任何想法?
ETA:耶稣,我讨厌这一点。这个问题是特别始终存在一个接口集合,但现在对进一步测试它不能用于正常的采集工作。下面是一些更简单的code:
ETA: Jesus, I'm sick of this. This problem was specifically about persisting an interface collection but now on further testing it doesn't work for a normal collection. Here's some even simpler code:
Public Class Anger
End Class
Public Class MyButton
Inherits Button
Private _Annoyance As List(Of Anger)
<DesignerSerializationVisibility(DesignerSerializationVisibility.Content)> _
Public ReadOnly Property Annoyance() As List(Of Anger)
Get
Return _Annoyance
End Get
End Property
Private _InternalAnger As Anger
<DesignerSerializationVisibility(DesignerSerializationVisibility.Content)> _
Public ReadOnly Property InternalAnger() As Anger
Get
Return Me._InternalAnger
End Get
End Property
Public Sub New()
Me._Annoyance = New List(Of Anger)
Me._InternalAnger = New Anger
Me._Annoyance.Add(Me._InternalAnger)
End Sub
End Class
设计者螺丝了持久code以同样的方式与原始问题
The designer screws up the persistence code in the same way as the original problem.
----原问题
要解释这个问题,最简单的办法是告诉你一些code:
The easiest way to explain this problem is to show you some code:
Public Interface IAmAnnoyed
End Interface
Public Class IAmAnnoyedCollection
Inherits ObjectModel.Collection(Of IAmAnnoyed)
End Class
Public Class Anger
Implements IAmAnnoyed
End Class
Public Class MyButton
Inherits Button
Private _Annoyance As IAmAnnoyedCollection
<DesignerSerializationVisibility(DesignerSerializationVisibility.Content)> _
Public ReadOnly Property Annoyance() As IAmAnnoyedCollection
Get
Return _Annoyance
End Get
End Property
Private _InternalAnger As Anger
<DesignerSerializationVisibility(DesignerSerializationVisibility.Content)> _
Public ReadOnly Property InternalAnger() As Anger
Get
Return Me._InternalAnger
End Get
End Property
Public Sub New()
Me._Annoyance = New IAmAnnoyedCollection
Me._InternalAnger = New Anger
Me._Annoyance.Add(Me._InternalAnger)
End Sub
End Class
这是code。该设计器生成:
And this is the code that the designer generates:
Private Sub InitializeComponent()
Dim Anger1 As Anger = New Anger
Me.MyButton1 = New MyButton
'
'MyButton1
'
Me.MyButton1.Annoyance.Add(Anger1)
// Should be: Me.MyButton1.Annoyance.Add(Me.MyButton1.InternalAnger)
'
'Form1
'
Me.Controls.Add(Me.MyButton1)
End Sub
我添加了评论上述说明如何在code应该已经产生。
I've added a comment to the above to show how the code should have been generated.
现在,如果我免除接口,只是有愤怒的集合,那么它坚持正确的。
Now, if I dispense with the interface and just have a collection of Anger, then it persists correctly.
任何想法?
推荐答案
正如我在任择议定书表示,这个问题归结为是我给的内部属性和收集的名称。
As i said in the OP, the problem boils down to the name that I give to the internal property and the collection.
如果没有钻研定制codeDOM序列化,简单的解决办法是,以确保内部属性的名字是按字母顺序排列的任何其他属性之前,将引用它。
Without delving into a custom codedom serializer, the simple solution is to make sure the internal property's name is alphabetically before any other property that will reference it.
我做到这一点,保留原属性名称InternalProperty',但我禁用系列化,它指的是代理性质,这是精明的命名,是序列化。
I do this by retaining the original property name 'InternalProperty', but I disable serialization and refer it to a proxy property, that is cunningly named, and is serialized.
Private _InternalProperty
Public ReadOnly Property InternalProperty
Get
Return Me._ProxyInternalProperty
End Get
End Property
<Browsable(False), EditorBrowsable(Never), DesignerSerializationVisibility(Content)> _
Public ReadOnly Property _ProxyInternalProperty
Get
Return Me._InternalProperty
End Get
End Property
这是一个黑客,但它不是重命名我的财产AInternalProperty更好。此外,用户不会看到_ProxyInternalProperty,因为它是隐藏的,即使他们没有发现它,没有在引用它没有危险。
This is a hack, but its better than renaming my property AInternalProperty. Also, the user will never see _ProxyInternalProperty because it's hidden, and even if they did discover it, there is no danger in referencing it.
这篇关于与持续的集合,引用了内部属性,在设计时的WinForms问题,.NET的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!