WithEvents variable giving Serialization Problems

rbulph

Well-known member
Joined
Feb 17, 2003
Messages
343
When I run the following code I get a message that the Parent class is not marked as serializable. This is very annoying since Im not trying to serialize the Parent. Is this is a bug in Visual Studio? How do I get around it?

Code:
Imports System.Runtime.Serialization.Formatters.Binary
Imports System.IO

Public Class Form1

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        Dim FileStream As Stream = File.Create("C:\abc.abc")

        Dim serializer As New BinaryFormatter
        With serializer
            
            Dim Child1 As New Child
            Dim Parent1 As Parent = New Parent(Child1)

            .Serialize(FileStream, Child1)  Get an error at this line - "Parent... is not marked as Serializable."

        End With

    End Sub
End Class

Public Class Parent
    Inherits PictureBox this is why I cant serialise the Parent class
    Friend WithEvents MyChild As Child

    Friend Sub New(ByVal newChild As Child)
        MyChild = newChild
        newChild.MyParent = Me
    End Sub

    Private Sub ChildNotify() Handles MyChild.InformParent
        
    End Sub
End Class

<Serializable()> Public Class Child

    Event InformParent()

    <NonSerialized()> Friend MyParent As Parent

End Class
 
It looks as though the automatic serialization support is attempting to serialize the target of the event (i.e. Parent) as this also happens if you dont declare it WithEvents but use the AddHandler statement instead.

If you implement the ISerializable interface however you have control over what does and doesnt get serialized - that should avoid this problem.
 
Thanks. If I mark Parent as Serializable, implement ISerializable in Parent, adding:

Code:
   Public Sub GetObjectData(ByVal info As System.Runtime.Serialization.SerializationInfo, ByVal context As System.Runtime.Serialization.StreamingContext) Implements System.Runtime.Serialization.ISerializable.GetObjectData

    End Sub

    Friend Sub New(ByVal info As System.Runtime.Serialization.SerializationInfo, ByVal context As System.Runtime.Serialization.StreamingContext)
        InitializeComponent()

    End Sub

so that, although Parent is serializable, nothing gets serialized, the problem seems to be resolved.
 
Problem is, the deserialization creates a ghost Parent to handle the events. Even if I put InitializeComponent in the new New Sub it doesnt seem to get created properly and there are errors when its constituent controls get referenced. If I try to Serialize the Parent property of Child, and then substitute the deserialized Parent with a new Parent, the problem doesnt go away.

Maybe the best solution is to simply remove all the event handling while Im saving and add it in as soon as Ive finished.
 
If the child class implements the ISerializable interface then you would save / load the required bits but just dont save anything regarding the event.
 
OK, after a break have gone back to this and got it to work, with some help from this article http://www.codeproject.com/KB/vb/serializevbclasses.aspx.

Outstanding problems are that it seems to take a lot of processor power to open files now and I have a static variable in one of my procedures that leads to an error sometimes on deserialization (field cant be found). Ive now marked this as nonserializable so hopefully that will do the trick.
 
The slowness seems to be the result of this (unrelated) code which is currently called during deserialization and which takes half a second to complete:

Code:
 Private Function PrintingArea() As Rectangle

        Return the area of the paper that printing is to take place on.
        With PrintDocument1.DefaultPageSettings
            Return New Rectangle(.Margins.Left, .Margins.Top, .Bounds.Width - .Margins.Left - .Margins.Right, .Bounds.Height - .Margins.Top - .Margins.Bottom)
        End With

    End Function

Dont know why this should be so slow.
 
Without profiling the code it is a bit speculative but I would be interested in knowing what the PrintDocument1.DefaultPageSettings is doing behind the scenes. It might be querying some OS / printer information - that could be taking the time.

It is possibly worth checking when / why this is being called and seeing if that could be addressed.
 
I suppose I could probably speed it up by just querying the Margins and Bounds once and storing them.
 
Back
Top