Question Data persistence in array object properties

gregsdennis

New member
Joined
Jan 10, 2011
Messages
4
Programming Experience
1-3
See code below:

VB.NET:
<Serializable()>
Public Class DataObject
    Implements ISerializable

    Dim txt As String = nothing
    Dim vlu As Integer = 0
    Public Property Text as String
        Get
            Return txt
        End Get
        Set(value As String)
            txt = value
        End Set
    End Property
    Public Property Val as Integer
        Get
            Return vlu
        End Get
        Set(value As Integer)
            vlu = value
        End Set
    End Property

    Public Sub New()
    End Sub
    Public Sub GetObjectData(ByVal info As SerializationInfo, ByVal context As StreamingContext) Implements ISerializable.GetObjectData
        If info IsNot Nothing Then
            info.AddValue("txt", txt)
            info.AddValue("vlu", vlu)
        End If
    End Sub
End Class

Public Class DataManager
    Inherits System.ComponentModel.Component

    Public Property DataList As List(Of DataObject)
End Class

I'm able to add the component to a form and access DataList just fine in the design view. But when I open the dialog to add objects to the list, it won't save. I can add objects, close the dialog, and when I reopen the dialog, there are no objects.

I've tried adding the New keyword in front of list with no luck. I have also tried explicitly declaring the DataList data member and using a Get/Set on the property, but that didn't work either.

Anyone know what's going on?
 
Last edited:
The fact that something is serialisable doesn;t mean that it is serialised. It simply means that it can be. I don't see any code there that is actually serialising the data or deserialising it again. You've got a GetDataObject method but no evidence that it's being called.
 
I was getting an error from the designer saying that my object wasn't serializable whenever I added a DataObject to the DataList member of DataManager, so I made it serializable. I don't really know why I was getting the error. I had never seen that error before, but I don't think I had ever tried to add objects to a collection at design time either. Anyway, it got rid of the serialization error.

Now the problem is that every time I rebuild, the DataList collection is emptied.
 
gregsdennis said:
Data persistence in array object properties
You're not persisting an array, the property in question get/set a List(Of T) collection. For this to work you have to set the property to ReadOnly and apply the DesignerSerializationVisibility attribute to serialize Content, here's an example:
VB.NET:
Private list As New List(Of DataObject)
<System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Content)> _
Public ReadOnly Property DataList() As List(Of DataObject)
    Get
        Return list
    End Get
End Property


When implementing ISerializable you must also include the appropriate constructor:
VB.NET:
Private Sub New(ByVal info As SerializationInfo, ByVal context As StreamingContext)
    Me.Text = info.GetString("txt")
    Me.Val = info.GetInt32("vlu")
End Sub
The parameterless constructor is also needed in conjunction with this, so that designer can create a new data object when you click Add in collection editor.

Currently ISerializable is not needed, the class members are serializable (to code) by the designer by default. You should remove ISerializable. When the Serializable attribute is applied you'll see the designer serializes the data object as resource objects, you should also remove this attribute and doing this you'll see designer now generates code to create the data objects, which is of course readable and easier to debug.

You'll end up with this data object class that is much simplified now (including using the short version of defining a property):
VB.NET:
Imports System.ComponentModel

Public Class DataObject
    <DefaultValue("")> Public Property Text() As String = ""
    <DefaultValue(0)> Public Property Val() As Integer
End Class
Notice also the DefaultValue attribute, which let this class play nicer along with designer.

One more note, I tested these cases with VB 2008 Express with no problems. With VB 2010 Express the serialization of the objects to resources (resx) produced 'invalid resx, could not load type' errors, which seems to be a bug.
 
Back
Top