Netron是一个C#开源图形库,能够帮助开发人员开发出相似Visio的做图软件。本文继前文”Netron开发快速上手(一)“讨论如何利用Netron里的序列化功能快速保存本身开发的图形对象。html
一个用Netron开发的实际应用请看:发布一个免费开源软件-- PAD流程图绘制软件PADFlowChartide
1、 Netron对象序列化函数
序列化Netron对象须要如下几个步骤:this
[Serializable] public class BlockShape : AbstractFlowChartShape
若是是从Shape类或Entity类(Shape类的父类)继承,则已经继承了ISerializable接口,你须要作的就是重载GetObjectData方法,该方法用于序列化时被序列化过程调用,提供要序列化的数据spa
public override void GetObjectData(SerializationInfo info, StreamingContext context) { base.GetObjectData(info, context); info.AddValue("m_leftConnector", m_leftConnector); … }
GetObjectData方法要先调用基类的方法,不然基类的数据不会被序列化。code
用info.AddValue()加入你要序列化的数据orm
类的序列化构造函数用于反序列化对象。当从磁盘读取序列化数据时,用于生成相应的对象。下面是个例子:htm
protected BlockShape(SerializationInfo info, StreamingContext context) : base(info, context) { m_leftConnector = (Connector)info.GetValue("m_leftConnector", typeof(Connector)); m_leftConnector.BelongsTo = this; Connectors.Add(m_leftConnector); … }
a) 注意要调用基类的序列化构造函数。对象
b) 用info.GetValue(“<数据名字>”,<数据类型>)来反序列化数据blog
IEntity::PostDeserialization()方法将会在Netron的反序列化过程当中被Netron.GraphLib.IO.Binary.BinarySerializer::UnwrapBundle()方法调用,调用的时机是全部对象创建之后。在这里你能够作一些初始化工做。由于反序列化时除了序列化构造函数其它的构造函数是不会被调用的。
2、 添加“打开/保存”代码
添加了图形对象的序列化代码后,你还须要在本身的应用程序中对“打开/保存”菜单命令添加相应的代码来打开/保存你的数据
GraphControl::Open()
GraphControl::SaveAs()
另外你能够用GraphControl::IsDirty来判断目前画布上的图形对象是否已经发生了改变须要保存;
GraphControl::OnDirtyChanged事件能够在画布上的内容发生改变后通知开发人员作相应的处理。
三、 Netron序列化过程分析
GraphControl:: SaveAs()
=>IO.Binary.BinarySerializer::SaveAs()
=> BinaryCapsule:: GetObjectData()
=>GraphAbstract:: GetObjectData()
而在GraphAbstract:: GetObjectData()里则分别序列化了其中的Shapes和Connections,对集合Shapes和Connections的序列化会致使Shape及Connection的GetObjectData()方法被调用。
GraphControl:: Open
=> IO.Binary.BinarySerializer:: Open()
=> BinaryFormatter:: Deserialize()
BinaryFormatter:: Deserialize()将会在读取序列化文件时调用相应对象的序列化构造函数进行反序列化。和前述序列化过程相反,反序列化过程会先调用Shape和Connection的序列化构造函数生成Shapes和Connections集合,而后调用GraphAbstract的序列化构造函数生成GrapAbstract对象,而后生成BinaryCapsule对象。
随后IO.Binary.BinarySerializer:: Open()将调用UnwrapBundle()方法,使Connection和Shape的Connector链接起来。由于在Netron中,Shape经过Connection相连,而Connection的From/To都指向Shape的Connector成员,在序列化过程当中,Connector对象是在Shape中进行序列化,而Connection则只序列化了From/To的UID(String类型); UnwrapBundle()方法将对每个Connection对象查找和From UID/To UID匹配的Connector,而后将Connection的From/To指向相应的Connector对象。
最后,在UnwrapBundle()方法中还会调用Shape和Connection的PostDeserialization()。