The easiest way to explain this problem is to show you the 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
And this is the code that the developer creates:
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
I added a comment to the above to show how the code should have been generated. Now, if I get around the interface and just have the Anger collection, it will be saved correctly.
Any ideas?
Update 1
I am tired of this. This problem was specifically related to saving the collection of interfaces, but now with further testing it does not work for a regular collection. Here is an 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
The designer spins the save code in the same way as the original problem.
Update 2
I worked out what was going on. I wondered why sometimes this works and not others. It comes down to the name I give to the home ownership and collection.
If I rename the "Annoyance" property to "WTF", it will serialize correctly, because "WTF" in alphabetical order after the collection name is "InternalAnger".
It appears that the serializer creates instances of objects in alphabetical order and requires that my internal property be created by the time the collection is created.
I can fix this by renaming, but itโs a hack, and Iโm afraid that writing my own serializer is a lot of work that Iโve never done before.
Any ideas?
Update 3
I answered the question with a hack. I am pretty sure of this if MS does not change the way the designer code serializers are encoded.