Netron開發快速上手(二):Netron序列化

 

Netron是一個C#開源圖形庫,能夠幫助開發人員開發出相似Visio的做圖軟件。本文繼前文」Netron開發快速上手(一)「討論如何利用Netron裏的序列化功能快速保存本身開發的圖形對象。html

一個用Netron開發的實際應用請看:發佈一個免費開源軟件-- PAD流程圖繪製軟件PADFlowChartide

1、      Netron對象序列化函數

序列化Netron對象須要如下幾個步驟:this

  • 添加序列化標籤]Serializable]
    [Serializable]

    public class BlockShape : AbstractFlowChartShape

 

 

  • 實現ISerializable接口

若是是從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()方法

IEntity::PostDeserialization()方法將會在Netron的反序列化過程當中被Netron.GraphLib.IO.Binary.BinarySerializer::UnwrapBundle()方法調用,調用的時機是全部對象創建之後。在這裏你能夠作一些初始化工做。由於反序列化時除了序列化構造函數其它的構造函數是不會被調用的。

 

2、      添加「打開/保存」代碼

添加了圖形對象的序列化代碼後,你還須要在本身的應用程序中對「打開/保存」菜單命令添加相應的代碼來打開/保存你的數據

  • 打開文件:

   GraphControl::Open()

  • 保存文件:

   GraphControl::SaveAs()

另外你能夠用GraphControl::IsDirty來判斷目前畫布上的圖形對象是否已經發生了改變須要保存;

GraphControl::OnDirtyChanged事件能夠在畫布上的內容發生改變後通知開發人員作相應的處理。

、      Netron序列化過程分析

  • Netron的序列化過程以下:

GraphControl:: SaveAs()

=>IO.Binary.BinarySerializer::SaveAs()

=> BinaryCapsule:: GetObjectData()

=>GraphAbstract:: GetObjectData()

而在GraphAbstract:: GetObjectData()裏則分別序列化了其中的Shapes和Connections,對集合Shapes和Connections的序列化會致使Shape及Connection的GetObjectData()方法被調用。

 

  • Netron的反序列化過程以下:

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()。

相關文章
相關標籤/搜索