Netron开发快速上手(二):Netron序列化
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序列化的更多相关文章
- Netron开发快速上手(一):GraphControl,Shape,Connector和Connection
版权所有,引用请注明出处:<<http://www.cnblogs.com/dragon/p/5203663.html >> 本文所用示例下载FlowChart.zip 一个用 ...
- Java开发快速上手
Java开发快速上手 前言 1.我的大学 2.对初学者的建议 3.大牛的三大特点 4.与他人的差距 第一章 了解Java开发语言 前言 基础常识 1.1 什么是Java 1.1.1 跨平台性 1.2 ...
- php扩展开发-快速上手
系统环境CentOS release 6.5 (Final) PHP版本php-5.6.27 扩展开发需要有php环境及php的源代码,我的PHP安装目录/home/zhangxiaomin/stud ...
- PhalApi 2.7 开发快速上手
PhalApi是一款国人制作的PHP纯后端框架.它的开发相当简单,同时也具备文档生成等特色功能.下面,我通过简单的几点,让你可以快速入门使用该框架的开发. 建议使用PHPStorm作为IDE,代码提示 ...
- react快速上手二(使用JSX语法)
前提: 下载依赖,配置 cnpm i babel-preset-react -D JSX语法的本质: 还是以 React.createElement 的形式来实现的,并没有直接把 用户写的 HTML代 ...
- [Full-stack] 快速上手开发 - React
故事背景 [1] 博客笔记结合<React快速上手开发>再次系统地.全面地走一遍. [2] React JS Tutorials:包含了JS --> React --> Red ...
- WebAPI调用笔记 ASP.NET CORE 学习之自定义异常处理 MySQL数据库查询优化建议 .NET操作XML文件之泛型集合的序列化与反序列化 Asp.Net Core 轻松学-多线程之Task快速上手 Asp.Net Core 轻松学-多线程之Task(补充)
WebAPI调用笔记 前言 即时通信项目中初次调用OA接口遇到了一些问题,因为本人从业后几乎一直做CS端项目,一个简单的WebAPI调用居然浪费了不少时间,特此记录. 接口描述 首先说明一下,基于 ...
- [译]:Xamarin.Android开发入门——Hello,Android快速上手
返回索引目录 原文链接:Hello, Android_Quickstart. 译文链接:Xamarin.Android开发入门--Hello,Android快速上手 本部分介绍利用Xamarin开发A ...
- 使用 CodeIgniter 框架快速开发 PHP 应用(二)
原文:使用 CodeIgniter 框架快速开发 PHP 应用(二) 二分钟: 建立一个 CodeIgniter 网站用CI建一个网站很容易. 这一章很短,解释了用CI制作网站时发生了些什么,哪些文件 ...
随机推荐
- 如何用ORM支持SQL语句的CASE WHEN?
OQL如何支持CASE WHEN? 今天,一个朋友问我,OQL可否支持CASE WHEN语句?他给的示例SQL如下: then '启用' else '停用' from tb_User OQL是SOD框 ...
- 使用CruiseControl.Net全面实现持续集成
持续集成想必大家很多人都听说过,甚至都实践过,最近我又一次亲历了一次持续集成,现将我的经验分享给大家.关于持续集成的理论在本文概不涉及,本文的主要目的是实战CruiseControl.Net,用它来全 ...
- JavaScript中数组去除重复
方式一:常规模式 1.构建一个新的临时数组存放结果 2.for循环中每次从原数组中取出一个元素,用这个元素循环与临时数组对比 3.若临时数组中没有该元素,则存到临时数组中 //方式一: Array.p ...
- jQuery中的事件处理
1.页面载入完毕响应事件所谓页面载入完毕是指DOM元素载入就绪了,能够被读取和操作了.①jQuery中的$(doucument).ready()事件ready(fn)是jQuery事件模块中最重要的一 ...
- CSS项目学习总结
1.我过去在HTML和CSS阶段是如何学习的? 我一开始学HTML和CSS,更多的是通过看视频.书籍,一个知识点一个知识点地去学习,很少把他们串联起来,看代码多于敲代码. 然而,通过现在这几个项目的实 ...
- iOS 多线程GCD的基本使用
<iOS多线程简介>中提到:GCD中有2个核心概念:1.任务(执行什么操作)2.队列(用来存放任务) 那么多线程GCD的基本使用有哪些呢? 可以分以下多种情况: 1.异步函数 + 并发队列 ...
- Objective-C 关键字:retain, assgin, copy, readonly,atomic,nonatomic
声明式属性的使用:声明式属性叫编译期语法 @property(retain,nonatomic)Some *s; @property(参数一,参数二)Some *s; 参数1:retain:修饰引用( ...
- centos 更换软件源
最近都在使用国内的VPS.系统统一使用的都是Linux系统.但是,有一些服务商的系统给默认设置的是国外的.这样就会导致下载速度缓慢.于是,找到了国内几家比较热门的镜像点.奉献给大家.下面的镜像全部支持 ...
- iOS开发中的http浅析
至于为什么要进行HTTP请求我就不说了.本文主要对HTTP协议做了一些介绍,主要针对网络编程和面试. 先从流程开始说起 APP <---> 服务器 <---> 后台 1) ...
- couchDB文档
每个文档都是自包含的数据单元,是一系列数据项的集合. 每个数据项都有一个名称与对应的值,值既可以是简单的数据类型,如字符串.数字和日期等:也可以是复杂的类型,如有序列表和关联对象. 每个文档都有一个全 ...