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. jquery在线五子棋

    在线五子棋试玩地址:http://keleyi.com/game/12/ 以下是完整代码,保存到html文件打开也可以玩: <!DOCTYPE html> <html> < ...

  2. js事件浅析

    js中关于DOM的操作很多,因此js事件机制也就尤为重要. 事件绑定形式: 一. 内联形式 耦合度高,不利于维护 <button onclick="alert('你点击了这个按钮'); ...

  3. angularjs+微信,解决chooseImage不能预览的问题

    在wx.chooseImage的success回调中直接进行数据绑定,却在ng-repeat时发现ng-src不加载微信localId的问题,类似wxLocalResource://imageid98 ...

  4. iOS中常见 Crash 及解决方案

    来源:枫影JustinYan 链接:http://justinyan.me/post/1609 一.访问了一个已经被释放的对象 在不使用 ARC 的时候,内存要自己管理,这时重复或过早释放都有可能导致 ...

  5. iOS面试题总结 (三)

    22 键值编码KVC KVC全称key valued coding 键值编码 提到KVC,就不能不提反射机制,反射机制就是在运行状态中,对于任意一个类,都能够调用他的所有属性和方法,对于任意一个对象, ...

  6. UIWebView加载本地html文件

    UIWebView *webView = [[UIWebView alloc] initWithFrame:CGRectMake(, , KScreenWidth, KScreenHeight-)]; ...

  7. iOS之 block,代替代理作为回调函数

    最近在弄一个视频会议的项目,但今天要说的跟视频基本没关系,我们来说一下在一个view中创建一个button,在controller中加载这个view 当button被点击后将时间响应传递给contro ...

  8. struts2默认配置文件 struts-default.xml

    注:用的struts2的版本是2.1.6 strtus2的默认配置文件 struts-default.xml ,其中的默认的拦截器,包括其中的拦截器栈. 因为struts2的配置文件struts.xm ...

  9. 为什么数据库有时候不能定位阻塞(Blocker)源头的SQL语句

    在SQL Server数据库或OACLE数据库当中,通常一个会话持有某个资源的锁,而另一个会话在请求这个资源,就会出现阻塞(blocking).这是DBA经常会遇到的情况.当出现SQL语句的阻塞时,很 ...

  10. Linux iptables 防火墙

    内容摘要 防火墙 防火墙定义 防火墙分类 netfilter/iptables netfilter 设计架构 iptables 简述 iptables 命令详解 命令语法 table 参数 comma ...