rbulph Posted April 29, 2008 Posted April 29, 2008 When I run the following code I get a message that the Parent class is not marked as serializable. This is very annoying since I'm not trying to serialize the Parent. Is this is a bug in Visual Studio? How do I get around it? 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 can't 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 Quote
Administrators PlausiblyDamp Posted April 29, 2008 Administrators Posted April 29, 2008 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 don't declare it WithEvents but use the AddHandler statement instead. If you implement the ISerializable interface however you have control over what does and doesn't get serialized - that should avoid this problem. Quote Posting Guidelines FAQ Post Formatting Intellectuals solve problems; geniuses prevent them. -- Albert Einstein
rbulph Posted May 1, 2008 Author Posted May 1, 2008 Thanks. If I mark Parent as Serializable, implement ISerializable in Parent, adding: 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. Quote
rbulph Posted May 1, 2008 Author Posted May 1, 2008 Problem is, the deserialization creates a ghost Parent to handle the events. Even if I put InitializeComponent in the new New Sub it doesn't seem to get created properly and there are errors when it's 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 doesn't go away. Maybe the best solution is to simply remove all the event handling while I'm saving and add it in as soon as I've finished. Quote
Administrators PlausiblyDamp Posted May 1, 2008 Administrators Posted May 1, 2008 If the child class implements the ISerializable interface then you would save / load the required bits but just don't save anything regarding the event. Quote Posting Guidelines FAQ Post Formatting Intellectuals solve problems; geniuses prevent them. -- Albert Einstein
rbulph Posted June 6, 2008 Author Posted June 6, 2008 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 can't be found). I've now marked this as nonserializable so hopefully that will do the trick. Quote
rbulph Posted June 6, 2008 Author Posted June 6, 2008 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: 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 Don't know why this should be so slow. Quote
Administrators PlausiblyDamp Posted June 6, 2008 Administrators Posted June 6, 2008 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. Quote Posting Guidelines FAQ Post Formatting Intellectuals solve problems; geniuses prevent them. -- Albert Einstein
rbulph Posted June 6, 2008 Author Posted June 6, 2008 I suppose I could probably speed it up by just querying the Margins and Bounds once and storing them. Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.