We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy. Image for the cookie policy date

Problem with Saving Diagram as soap. MetaFileNode not serializable!

I have a diagram which used a custom symbol. The symbol contain a MetaFileNode. When I try to save the diagram using SaveSoap I get an error saying that the MetaFileNode is not marked as serializable. Is there a solution so I can save the diagram? Here is my class using System; using System.Drawing; using Syncfusion.Windows.Forms.Diagram; namespace HomeConductor.App.Composer { /// /// Summary description for DeviceSymbol. /// [Serializable()] public class DeviceSymbol : Symbol { public DeviceSymbol(string filename) { ////////////////////////////////////////////////////////////////// // Add child nodes to the symbol programmatically ////////////////////////////////////////////////////////////////// InsertNodesCmd cmd = new InsertNodesCmd(); System.Drawing.GraphicsUnit graphunit = new GraphicsUnit(); graphunit = GraphicsUnit.Pixel; System.Drawing.Imaging.Metafile file = new System.Drawing.Imaging.Metafile(filename); System.Drawing.RectangleF rect = new RectangleF(100, 100, file.Width, file.Height); MetafileNode metaFileNode = new MetafileNode(file, RectangleF.Inflate(rect, 0, 0), graphunit); this.AppendChild(metaFileNode); //Add these lines to DeviceSymbol''s Constructor this.Ports.Add(new AnchoredPort(this, BoxPosition.TopLeft)); this.Ports.Add(new AnchoredPort(this, BoxPosition.TopRight)); this.Ports.Add(new AnchoredPort(this, BoxPosition.TopCenter)); this.Ports.Add(new AnchoredPort(this, BoxPosition.BottomLeft)); this.Ports.Add(new AnchoredPort(this, BoxPosition.BottomCenter)); this.Ports.Add(new AnchoredPort(this, BoxPosition.BottomRight)); this.Ports.Add(new AnchoredPort(this, BoxPosition.MiddleLeft)); this.Ports.Add(new AnchoredPort(this, BoxPosition.MiddleRight)); foreach (AnchoredPort port in this.Ports) { // loads the circle crosshair instead of the x port port.Load(PortVisuals.CirclePort); port.Visible = false; } } } }

6 Replies

ES Eric Silver December 21, 2004 07:05 PM UTC

Here is the error I get See the end of this message for details on invoking just-in-time (JIT) debugging instead of this dialog box. ************** Exception Text ************** System.Runtime.Serialization.SerializationException: The type Syncfusion.Windows.Forms.Diagram.MetafileNode in Assembly Syncfusion.Diagram.Base, Version=3.0.0.19, Culture=neutral, PublicKeyToken=3d67ed1f87d44c89 is not marked as serializable. at System.Runtime.Serialization.Formatters.Soap.WriteObjectInfo.InitSerialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, SoapAttributeInfo attributeInfo) at System.Runtime.Serialization.Formatters.Soap.WriteObjectInfo.Serialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, SoapAttributeInfo attributeInfo) at System.Runtime.Serialization.Formatters.Soap.ObjectWriter.Serialize(Object graph, Header[] inHeaders, SoapWriter serWriter) at System.Runtime.Serialization.Formatters.Soap.SoapFormatter.Serialize(Stream serializationStream, Object graph, Header[] headers) at System.Runtime.Serialization.Formatters.Soap.SoapFormatter.Serialize(Stream serializationStream, Object graph) at Syncfusion.Windows.Forms.Diagram.Controls.Diagram.SaveSoap(Stream strmOut) at Syncfusion.Windows.Forms.Diagram.Controls.Diagram.SaveSoap(String fileName)


AD Administrator Syncfusion Team December 22, 2004 02:13 PM UTC

Hi Eric, Essential Diagram Symbol types require that the System.Runtime.Serialization.ISerializable interface be implemented in the class for proper serialization. There is an Essential Diagram Knowledgebase article that outlines the details involved and also provides sample code that shows a custom symbol class with serializable data members. Please refer to the following link - http://www.syncfusion.com/Support/article.aspx?id=10492. Regards, Prakash, Syncfusion, Inc.


ES Eric Silver December 22, 2004 02:38 PM UTC

Ok I think I got most of what the post said. Here is my latest version of the class. When saving diagram I am still getting the error. using System; using System.Drawing; using Syncfusion.Windows.Forms.Diagram; using System.ComponentModel; using System.Globalization; using System.Runtime.Serialization; namespace HomeConductor.App.Composer { /// /// Summary description for DeviceSymbol. /// [Serializable()] public class DeviceSymbol : Symbol { public DeviceSymbol(string filename) { ImageFileName = filename; CreateSymbol(); } public void CreateSymbol() { ////////////////////////////////////////////////////////////////// // Add child nodes to the symbol programmatically ////////////////////////////////////////////////////////////////// InsertNodesCmd cmd = new InsertNodesCmd(); System.Drawing.GraphicsUnit graphunit = new GraphicsUnit(); graphunit = GraphicsUnit.Pixel; System.Drawing.Imaging.Metafile file = new System.Drawing.Imaging.Metafile(ImageFileName); System.Drawing.RectangleF rect = new RectangleF(100, 100, file.Width, file.Height); MetafileNode metaFileNode = new MetafileNode(file, RectangleF.Inflate(rect, 0, 0), graphunit); this.AppendChild(metaFileNode); //Add these lines to DeviceSymbol''s Constructor this.Ports.Add(new AnchoredPort(this, BoxPosition.TopLeft)); this.Ports.Add(new AnchoredPort(this, BoxPosition.TopRight)); this.Ports.Add(new AnchoredPort(this, BoxPosition.TopCenter)); this.Ports.Add(new AnchoredPort(this, BoxPosition.BottomLeft)); this.Ports.Add(new AnchoredPort(this, BoxPosition.BottomCenter)); this.Ports.Add(new AnchoredPort(this, BoxPosition.BottomRight)); this.Ports.Add(new AnchoredPort(this, BoxPosition.MiddleLeft)); this.Ports.Add(new AnchoredPort(this, BoxPosition.MiddleRight)); foreach (AnchoredPort port in this.Ports) { // loads the circle crosshair instead of the x port port.Load(PortVisuals.CirclePort); port.Visible = false; } } protected string ImageFileName; /// /// Copy constructor. /// /// public DeviceSymbol(DeviceSymbol src) : base(src) { } /// /// Serialization constructor for the MySymbol class. /// /// Serialization state information /// Streaming context information protected DeviceSymbol(SerializationInfo info, StreamingContext context) : base(info, context) { // The Serialization constructor is invoked during deserialization or during a drag & drop operation. // If the MySymbol type has serializable members, then initialize them with the serialized data // obtained from the SerializationInfo param // Read the bClrFlag member value from the SerializationInfo object this.ImageFileName = info.GetString("ImageFileName"); } // Override SymbolBase.GetObjectData() and populate the SerializationInfo param // with the data (if any) that belongs to the MySymbol type . This data will be // serialized as a part of the Symbol object. protected override void GetObjectData(SerializationInfo info, StreamingContext context) { base.GetObjectData(info, context); // Populate the SerializationInfo object with the bClrFlag member data info.AddValue("ImageFileName", this.ImageFileName); } } }


ES Eric Silver December 22, 2004 02:54 PM UTC

It is possible the problem is not in the symboc class code. Basically it creates a new node and add it to the diagram. The new node is a MetaFileNode object. Is it possible that when the diagram is serialised it attempts to serialise the metafile node anyway thus causing the error to occur?


AD Administrator Syncfusion Team December 22, 2004 03:20 PM UTC

Eric, Upon double checking based on your update I figured out what the problem was. I am sorry but the serialization error is the result of an oversight in the Essential Diagram MetaFileNode class. I noticed that the Syncfusion.Windows.Forms.Diagram.MetaFileNode class does not include the ''Serializable'' attribute that is required for serialization. I have made the necessary fix and the next update of Essential Diagram will ship with the revised code. For the time being, you can workaround this condition by using the appended custom implementation of the MetaFileNode in your Symbol class in place of the default Diagram MetaFileNode type. My apologies for the inconvenience. Please let me know if you have trouble with the workaround. If there are any formatting issues with the appended source code, please send an email to ''prakashs@syncfusion.com'' referring to this forum post and I will send it over. Regards, Prakash // Custom MetaFileNode class that can be used till the next update of Essential Diagram /// /// Stores and renders an enhanced metafile image. /// [Serializable] public class CustomMetafileNode : ImageNode { public CustomMetafileNode() { this.metafile = null; } public CustomMetafileNode(System.IO.Stream stream) { this.metafile = new System.Drawing.Imaging.Metafile(stream); this.imageBounds = this.metafile.GetBounds(ref this.grfxUnit); } public CustomMetafileNode(string filename) { this.metafile = new System.Drawing.Imaging.Metafile(filename); this.imageBounds = this.metafile.GetBounds(ref this.grfxUnit); } public CustomMetafileNode(System.Drawing.Imaging.Metafile metafile) { this.metafile = metafile; this.imageBounds = this.metafile.GetBounds(ref this.grfxUnit); } public CustomMetafileNode(System.Drawing.Imaging.Metafile metafile, RectangleF bounds, System.Drawing.GraphicsUnit grfxUnit) { this.metafile = metafile; this.imageBounds = bounds; this.grfxUnit = grfxUnit; } // Serialization constructor for bitmaps. protected CustomMetafileNode(SerializationInfo info, StreamingContext context) : base(info, context) { this.metafile = (System.Drawing.Imaging.Metafile) info.GetValue("metafile", typeof(System.Drawing.Imaging.Metafile)); this.grfxUnit = (System.Drawing.GraphicsUnit) info.GetValue("grfxUnit", typeof(System.Drawing.GraphicsUnit)); } public CustomMetafileNode(CustomMetafileNode src) : base(src) { this.metafile = (System.Drawing.Imaging.Metafile) src.metafile.Clone(); this.grfxUnit = src.grfxUnit; } // Creates a new object that is a copy of the current instance. public override object Clone() { return new CustomMetafileNode(this); } public override System.Drawing.Image Image { get { return this.metafile; } } public override System.Drawing.GraphicsUnit GraphicsUnit { get { return this.grfxUnit; } } // Populates a SerializationInfo with the data needed to serialize the target object. protected override void GetObjectData(SerializationInfo info, StreamingContext context) { base.GetObjectData(info, context); info.AddValue("metafile", this.metafile); info.AddValue("grfxUnit", this.grfxUnit); } private System.Drawing.Imaging.Metafile metafile = null; private System.Drawing.GraphicsUnit grfxUnit = GraphicsUnit.Pixel; }


ES Eric Silver December 22, 2004 04:24 PM UTC

Thanks for the updated class diagram. I will take your revised code and test it in my project. >Eric, > >Upon double checking based on your update I figured out what the problem was. I am sorry but the serialization error is the result of an oversight in the Essential Diagram MetaFileNode class. I noticed that the Syncfusion.Windows.Forms.Diagram.MetaFileNode class does not include the ''Serializable'' attribute that is required for serialization. I have made the necessary fix and the next update of Essential Diagram will ship with the revised code. > >For the time being, you can workaround this condition by using the appended custom implementation of the MetaFileNode in your Symbol class in place of the default Diagram MetaFileNode type. > >My apologies for the inconvenience. Please let me know if you have trouble with the workaround. If there are any formatting issues with the appended source code, please send an email to ''prakashs@syncfusion.com'' referring to this forum post and I will send it over. > >Regards, >Prakash > > >// Custom MetaFileNode class that can be used till the next update of Essential Diagram >/// >/// Stores and renders an enhanced metafile image. >/// >[Serializable] >public class CustomMetafileNode : ImageNode >{ > public CustomMetafileNode() > { > this.metafile = null; > } > > public CustomMetafileNode(System.IO.Stream stream) > { > this.metafile = new System.Drawing.Imaging.Metafile(stream); > this.imageBounds = this.metafile.GetBounds(ref this.grfxUnit); > } > > public CustomMetafileNode(string filename) > { > this.metafile = new System.Drawing.Imaging.Metafile(filename); > this.imageBounds = this.metafile.GetBounds(ref this.grfxUnit); > } > > public CustomMetafileNode(System.Drawing.Imaging.Metafile metafile) > { > this.metafile = metafile; > this.imageBounds = this.metafile.GetBounds(ref this.grfxUnit); > } > > public CustomMetafileNode(System.Drawing.Imaging.Metafile metafile, RectangleF bounds, System.Drawing.GraphicsUnit grfxUnit) > { > this.metafile = metafile; > this.imageBounds = bounds; > this.grfxUnit = grfxUnit; > } > > // Serialization constructor for bitmaps. > protected CustomMetafileNode(SerializationInfo info, StreamingContext context) : base(info, context) > { > this.metafile = (System.Drawing.Imaging.Metafile) info.GetValue("metafile", typeof(System.Drawing.Imaging.Metafile)); > this.grfxUnit = (System.Drawing.GraphicsUnit) info.GetValue("grfxUnit", typeof(System.Drawing.GraphicsUnit)); > } > > public CustomMetafileNode(CustomMetafileNode src) : base(src) > { > this.metafile = (System.Drawing.Imaging.Metafile) src.metafile.Clone(); > this.grfxUnit = src.grfxUnit; > } > > // Creates a new object that is a copy of the current instance. > public override object Clone() > { > return new CustomMetafileNode(this); > } > > public override System.Drawing.Image Image > { > get { return this.metafile; } > } > > public override System.Drawing.GraphicsUnit GraphicsUnit > { > get { return this.grfxUnit; } > } > > // Populates a SerializationInfo with the data needed to serialize the target object. > protected override void GetObjectData(SerializationInfo info, StreamingContext context) > { > base.GetObjectData(info, context); > info.AddValue("metafile", this.metafile); > info.AddValue("grfxUnit", this.grfxUnit); > } > > private System.Drawing.Imaging.Metafile metafile = null; > private System.Drawing.GraphicsUnit grfxUnit = GraphicsUnit.Pixel; >} >

Loader.
Live Chat Icon For mobile
Up arrow icon