Netron是一个C#开源图形库,可以帮助开发人员开发出类似Visio的作图软件。本文继前文”Netron开发快速上手(一)“讨论如何利用Netron里的序列化功能快速保存自己开发的图形对象。

一个用Netron开发的实际应用请看:发布一个免费开源软件-- PAD流程图绘制软件PADFlowChart

一、      Netron对象序列化

序列化Netron对象需要以下几个步骤:

  • 添加序列化标签]Serializable]
    [Serializable]

    public class BlockShape : AbstractFlowChartShape
  • 实现ISerializable接口

如果是从Shape类或Entity类(Shape类的父类)继承,则已经继承了ISerializable接口,你需要做的就是重载GetObjectData方法,该方法用于序列化时被序列化过程调用,提供要序列化的数据

        public override void GetObjectData(SerializationInfo info, StreamingContext context)

        {

            base.GetObjectData(info, context);

            info.AddValue("m_leftConnector", m_leftConnector);

                       …

        }

GetObjectData方法要先调用基类的方法,否则基类的数据不会被序列化。

用info.AddValue()加入你要序列化的数据

  • 实现序列化的构造函数

类的序列化构造函数用于反序列化对象。当从磁盘读取序列化数据时,用于生成相应的对象。下面是个例子:

        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(“<数据名字>”,<数据类型>)来反序列化数据

  • 必要时重载IEntity:PostDeserialization()方法

IEntity::PostDeserialization()方法将会在Netron的反序列化过程中被Netron.GraphLib.IO.Binary.BinarySerializer::UnwrapBundle()方法调用,调用的时机是所有对象建立以后。在这里你可以做一些初始化工作。因为反序列化时除了序列化构造函数其它的构造函数是不会被调用的。

二、      添加“打开/保存”代码

添加了图形对象的序列化代码后,你还需要在自己的应用程序中对“打开/保存”菜单命令添加相应的代码来打开/保存你的数据

  • 打开文件:

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

Netron开发快速上手(二):Netron序列化的更多相关文章

  1. Netron开发快速上手(一):GraphControl,Shape,Connector和Connection

    版权所有,引用请注明出处:<<http://www.cnblogs.com/dragon/p/5203663.html >> 本文所用示例下载FlowChart.zip 一个用 ...

  2. Java开发快速上手

    Java开发快速上手 前言 1.我的大学 2.对初学者的建议 3.大牛的三大特点 4.与他人的差距 第一章 了解Java开发语言 前言 基础常识 1.1 什么是Java 1.1.1 跨平台性 1.2 ...

  3. php扩展开发-快速上手

    系统环境CentOS release 6.5 (Final) PHP版本php-5.6.27 扩展开发需要有php环境及php的源代码,我的PHP安装目录/home/zhangxiaomin/stud ...

  4. PhalApi 2.7 开发快速上手

    PhalApi是一款国人制作的PHP纯后端框架.它的开发相当简单,同时也具备文档生成等特色功能.下面,我通过简单的几点,让你可以快速入门使用该框架的开发. 建议使用PHPStorm作为IDE,代码提示 ...

  5. react快速上手二(使用JSX语法)

    前提: 下载依赖,配置 cnpm i babel-preset-react -D JSX语法的本质: 还是以 React.createElement 的形式来实现的,并没有直接把 用户写的 HTML代 ...

  6. [Full-stack] 快速上手开发 - React

    故事背景 [1] 博客笔记结合<React快速上手开发>再次系统地.全面地走一遍. [2] React JS Tutorials:包含了JS --> React --> Red ...

  7. WebAPI调用笔记 ASP.NET CORE 学习之自定义异常处理 MySQL数据库查询优化建议 .NET操作XML文件之泛型集合的序列化与反序列化 Asp.Net Core 轻松学-多线程之Task快速上手 Asp.Net Core 轻松学-多线程之Task(补充)

    WebAPI调用笔记   前言 即时通信项目中初次调用OA接口遇到了一些问题,因为本人从业后几乎一直做CS端项目,一个简单的WebAPI调用居然浪费了不少时间,特此记录. 接口描述 首先说明一下,基于 ...

  8. [译]:Xamarin.Android开发入门——Hello,Android快速上手

    返回索引目录 原文链接:Hello, Android_Quickstart. 译文链接:Xamarin.Android开发入门--Hello,Android快速上手 本部分介绍利用Xamarin开发A ...

  9. 使用 CodeIgniter 框架快速开发 PHP 应用(二)

    原文:使用 CodeIgniter 框架快速开发 PHP 应用(二) 二分钟: 建立一个 CodeIgniter 网站用CI建一个网站很容易. 这一章很短,解释了用CI制作网站时发生了些什么,哪些文件 ...

随机推荐

  1. C#枚举、结构、数组、排序

  2. Android Touch事件传递机制 二:单纯的(伪生命周期)

    转载于:http://blog.csdn.net/yuanzeyao/article/details/38025165 在前一篇文章中,我主要讲解了Android源码中的Touch事件的传递过程,现在 ...

  3. iOS导航栏标题颜色

    按钮的颜色 [self.navigationBar setTintColor:[UIColor whiteColor]]; 标题颜色.字体 [self.navigationBar setTitleTe ...

  4. initialize和init以及load方法的区别与使用以及什么时候调用

    initialize不是init initialize在这个类第一次被调用的时候比如[[class alloc]init]会调用一次initialize方法,不管创建多少次这个类,都只会调用一次这个方 ...

  5. 又一个高性能轻量级的iOS模型框架YYModel

    前言 iOS的模型框架其实有很多了,去年研究过Mantle,也了解过JSONModel.MJExtension,最近的项目项目优化的时候,再次考虑,基于轻量级.高性能的考虑,最终选择了YYModel. ...

  6. C# Enum,Int,String的互相转换

    版权声明:本文为博主原创文章,未经博主允许不得转载. Enum为枚举提供基类,其基础类型可以是除 Char 外的任何整型.如果没有显式声明基础类型,则使用Int32.编程语言通常提供语法来声明由一组已 ...

  7. RedHat 4下无resize2fs命令

    在Red Hat Enterprise Linux AS release 4上进行LVM扩展分区时,发现RedHat 4下没有resize2fs,不过可以用ext2online替换resize2fs. ...

  8. MYSQL多实例配置方法 mysqld_multi方法

    在实际的开发过程中,可能会需要在一台服务器上部署多个MYSQL实例,那建议使用MYSQL官方的解决方案 mysqld_multi 1.修改my.cnf 如一个定义两个实例的参考配置: [mysqld_ ...

  9. date命令总结

    date命令是显示或设置系统时间与日期 date(选项)(参数) -d<字符串>:显示字符串所指的日期与时间.字符串前后必须加上双引号: -s<字符串>:根据字符串来设置日期与 ...

  10. 【hbase】——bulk load导入数据时value=\x00\x00\x00\x01问题解析

    一.存入数据类型 Hbase里面,rowkey是按照字典序进行排序.存储的value值,当用filter进行数据筛选的时候,所用的比较算法也是字典序的. 1.当存储的value值是float类型的时候 ...