西安网站维护兼职,火币网站怎么做空,wordpress 用户 权限,做网站代理怎么赚钱目录 序列化保存C# 代码示例#xff0c; 方式1 #xff1a;C# 代码示例#xff0c; 方式2 #xff1a; 反序列化加载C# 代码示例, 方式1#xff1a;C# 代码示例, 方式2#xff1a; **如何序列化自定义属性**序列化和反序列化都存在的一个问题解决方式 图表是否已修改 方式1 C# 代码示例 方式2 反序列化加载C# 代码示例, 方式1C# 代码示例, 方式2 **如何序列化自定义属性**序列化和反序列化都存在的一个问题解决方式 图表是否已修改如何在新版本中加载SfDiagram的旧版本 序列化
序列化是将SfDiagram对象的状态转换为字节流的过程以便在需要时重新创建它们。这样的流可以存储在数据库中、作为文件或内存中。相反的过程称为反序列化。
保存
在SfDiagram中使用DataContractSerializer进行序列化。DataContractSerializer的功能适用于SfDiagram序列化。它支持将SfDiagram保存到流中。SfDiagram会连同其所有属性一起被保存。
C# 代码示例 方式1
// 将文件保存为流
SaveFileDialog dialog new SaveFileDialog();
dialog.Title 保存XAML;
dialog.Filter XAML文件(*.xaml)|*.xaml;
if (dialog.ShowDialog() true)
{using (Stream str File.Open(dialog.FileName, FileMode.CreateNew)){sfDiagram.Save(str);}
}C# 代码示例 方式2 // 将保存为内存流FileMode.Create 会覆盖已有的FileMode.CreateNew 不会覆盖已有的using (Stream str File.Open(GlobalData.Instance.WfFullName, FileMode.Create)){diagram.Save(str);}反序列化
加载
在反序列化过程中使用保存的流来加载当前视图中的SfDiagram节点和连接器。通过这种方式你可以通过加载适当的流继续处理之前保存的SfDiagram。
C# 代码示例, 方式1
// 从保存的XAML文件中加载
OpenFileDialog dialog new OpenFileDialog();
if (dialog.ShowDialog() true)
{using (Stream myStream dialog.OpenFile()){sfDiagram.Load(myStream);}
}C# 代码示例, 方式2
// 从保存的内存流中加载
using (FileStream fileStream new FileStream(FullName, FileMode.Open, FileAccess.Read))
{diagram.Load(fileStream);
}如何序列化自定义属性
在SfDiagram中你不能序列化每个图表对象的Content和ContentTemplate。如果你想保留图表对象的ContentTemplate请将它们保存在资源中并在图表对象添加到图表页面后应用它们。
自定义类中的自定义属性如果从SfDiagram的任何接口或任何视图模型类派生则可以通过DataMember属性进行序列化。
C# 代码示例
public class NodeContent : INode
{[DataMember]public string NodeType{get;set;}
}也就是说只要你添加了[DataMember]特性你自己添加的属性也会被序列化 但前提是你的这个类是从SfDiagram的接口或任何视图模型类派生的。
注意
SfDiagram的接口和视图模型类是在没有DataContract属性的情况下创建的。因此对于从这些类派生的类你不需要添加DataContract属性。
如何序列化自定义类
您可以借助 DataContract 属性和 SfDiagram 的 KnownTypes 属性来序列化业务类。您必须添加 DataContract 属性来序列化整个类。 再说一次人话 在进行序列化操作时如果你有一个业务类business class并且这个类没有从任何已经标记了DataContract属性的基类base class继承那么你需要给这个类添加DataContract属性来序列化整个类。简而言之如果一个类没有继承自一个已经定义了DataContract属性的基类那么你需要为这个类本身添加DataContract属性以便能够对其进行序列化。 C# 代码示例
[DataContract]
public class NodeContent
{[DataMember]public string NodeType{get;set;}
}Diagram.KnownTypes () new ListType()
{typeof(NodeContent)
};序列化和反序列化都存在的一个问题
我自己定义一个继承自SfDiagram的接口和视图模型类的类
public class VisualNode : BpmnNodeViewModel
{[DataMember]public string? IDString { get; set; } null;/// summary/// 为view窗口名称用于打开对于节点窗口/// /summary[DataMember]public string NodeViewType { get; set; } Activity;/// summary/// 工作流节点类型/// /summary[DataMember]public string StepType { get; set; } ;/// summary/// 记录输入参数(为了方便Diagram自带的序列化可以进行这里需要改为string类型)/// /summary[DataMember]public JObject Inputs { get; set; } null;/// summary/// 记录输出参数(为了方便Diagram自带的序列化可以进行这里需要改为string类型)/// /summary[DataMember]public JObject Outputs { get; set; } null;
}在C#中使用序列化时如果遇到System.Runtime.Serialization.InvalidDataContractException错误特别是涉及到Newtonsoft.Json.Linq.JToken类型时通常是因为JToken类型是一个递归集合数据这在序列化过程中不被支持。错误信息提示“Type ‘Newtonsoft.Json.Linq.JToken’ is a recursive collection data contract which is not supported. Consider modifying the definition of collection ‘Newtonsoft.Json.Linq.JToken’ to remove references to itself.”。
JToken包括JObject和JArray由于其设计为可以包含自身类型的实例例如一个JObject可以包含另一个JObject作为其属性值导致了递归定义这在数据契约序列化中是不被允许的。
解决方式
将他们改成string 格式 /// /summary[DataMember]public string Inputs { get; set; } {};/// summary/// 记录输出参数(为了方便Diagram自带的序列化可以进行这里需要改为string类型)/// /summary[DataMember]public string Outputs { get; set; } {};JObject 存的时候先序列化
node.Outputs JsonConvert.SerializeObject(obj);JObject 用的时候再反序列化即可
jsonStepData.Outputs JsonConvert.DeserializeObjectJObject(FirstFuncNode.Outputs);图表是否已修改
图表控件的HasChanges属性用于通知图表是否有未保存的更改。该属性跟踪通过交互和公共API所做的所有更改。
XAML 代码示例
!-- 初始化图表 --
Syncfusion:SfDiagram x:Namediagram
/Syncfusion:SfDiagram
!-- 初始化保存图表的按钮 --
Button x:NameSaveButton Content保存 ClickSaveButton_Click
/Button//Method to promote the save dialouge box when diagram has any unsaved changes.
private void SaveButton_Click(object sender, RoutedEventArgs e)
{if (diagram ! null diagram.HasChanges){MessageBoxResult messageBoxResult MessageBox.Show(Do you want to save the Diagram?,SfDiagram,MessageBoxButton.YesNo);if (messageBoxResult MessageBoxResult.Yes){SaveDiagram();}}
}//Method to save the diagram.
private void SaveDiagram()
{SaveFileDialog dialog new SaveFileDialog();dialog.Title Save XAML;dialog.Filter XAML File (*.xaml)|*.xaml;if (dialog.ShowDialog() true){File.Delete(dialog.FileName);using (Stream s File.Open(dialog.FileName, FileMode.OpenOrCreate)){diagram.Save(s);}}
}如何在新版本中加载SfDiagram的旧版本
你可以通过升级方法在新版本中加载任何旧版本的SfDiagram流。请参考以下代码示例。
C# 代码示例
using (Stream myStream dialog.OpenFile())
{sfDiagram.Upgrade(myStream);sfDiagram.Load(myStream);
}