序列化树视图时丢失数据
Lost data when serializing treeview
我正在用 C# 编写程序,它将数据分配给 class,然后将 class 分配给树视图节点的标签值。
我可以使用我在此处找到的答案将我的树视图序列化为文件:Saving content of a treeview to a file and load it later。
但是,在反序列化文件时,所有节点的标签都丢失了,或者更可能的是,它们根本就没有被序列化。
使用此方法序列化时是否可以保留节点的标签值?如果可以,怎么做?
待BinaryFormatter
, your Tag
object must be marked as [Serializable]
, which indicates that it can be successfully serialized and deserialized by serializing its public and private fields. If it is so marked, then it will be serialized as part of a TreeNode
, as is shown by the reference source序列化成功:
[TypeConverterAttribute(typeof(TreeNodeConverter)), Serializable,
DefaultProperty("Text"),
SuppressMessage("Microsoft.Usage", "CA2240:ImplementISerializableCorrectly")]
public class TreeNode : MarshalByRefObject, ICloneable, ISerializable {
object userData;
protected virtual void Serialize(SerializationInfo si, StreamingContext context) {
// SNIP storage of irrelevant fields.
if (userData != null && userData.GetType().IsSerializable) {
si.AddValue("UserData", userData, userData.GetType());
}
}
public object Tag {
get {
return userData;
}
set {
userData = value;
}
}
}
请注意,如果您的 Tag
对象 不可 可序列化,它将被静默跳过;不会抛出异常。
我想改进这个答案。
在 class 之前使用 [Serializable()]
并且 class 派生自 ISerializable
。
很重要
此外,可以接受反序列化参数的重载构造函数的存在 和 GetObjectData
函数很重要。
本质上,GetObjectData
函数为序列化程序提供了将所有信息作为字符串访问的能力,而重载的 NodeTag
构造函数可以重新解释序列化的字符串数据并将其加载回对象。
我必须按照以下方式构建我的 class(这是半伪代码):
[Serializable()]
class NodeTag : ISerializable
{
public NodeTag(string Subnet)
{
Broadcast_Address = Stuff;
Network_Name = Stuff;
CIDR_Value = Stuff;
}
public string Network_Name { get; set; }
public string CIDR_Value { get; set; }
public string Broadcast_Address { get; set; }
//Deserializer - loads back from file data
//This is an overloaded function that defines the data object when it is being reconstituted
public NodeTag(SerializationInfo info, StreamingContext context)
{
Network_Name = (String)info.GetValue("Network_Name", typeof(string));
CIDR_Value = (String)info.GetValue("CIDR_Value", typeof(string));
Broadcast_Address = (String)info.GetValue("Broadcast_Address", typeof(string));
}
//Serializer - loads into file data
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("Network_Name", Network_Name);
info.AddValue("CIDR_Value", CIDR_Value);
info.AddValue("Broadcast_Address", Broadcast_Address);
}
}
我正在用 C# 编写程序,它将数据分配给 class,然后将 class 分配给树视图节点的标签值。
我可以使用我在此处找到的答案将我的树视图序列化为文件:Saving content of a treeview to a file and load it later。
但是,在反序列化文件时,所有节点的标签都丢失了,或者更可能的是,它们根本就没有被序列化。
使用此方法序列化时是否可以保留节点的标签值?如果可以,怎么做?
待BinaryFormatter
, your Tag
object must be marked as [Serializable]
, which indicates that it can be successfully serialized and deserialized by serializing its public and private fields. If it is so marked, then it will be serialized as part of a TreeNode
, as is shown by the reference source序列化成功:
[TypeConverterAttribute(typeof(TreeNodeConverter)), Serializable,
DefaultProperty("Text"),
SuppressMessage("Microsoft.Usage", "CA2240:ImplementISerializableCorrectly")]
public class TreeNode : MarshalByRefObject, ICloneable, ISerializable {
object userData;
protected virtual void Serialize(SerializationInfo si, StreamingContext context) {
// SNIP storage of irrelevant fields.
if (userData != null && userData.GetType().IsSerializable) {
si.AddValue("UserData", userData, userData.GetType());
}
}
public object Tag {
get {
return userData;
}
set {
userData = value;
}
}
}
请注意,如果您的 Tag
对象 不可 可序列化,它将被静默跳过;不会抛出异常。
我想改进这个答案。
在 class 之前使用 [Serializable()]
并且 class 派生自 ISerializable
。
此外,可以接受反序列化参数的重载构造函数的存在 和 GetObjectData
函数很重要。
本质上,GetObjectData
函数为序列化程序提供了将所有信息作为字符串访问的能力,而重载的 NodeTag
构造函数可以重新解释序列化的字符串数据并将其加载回对象。
我必须按照以下方式构建我的 class(这是半伪代码):
[Serializable()]
class NodeTag : ISerializable
{
public NodeTag(string Subnet)
{
Broadcast_Address = Stuff;
Network_Name = Stuff;
CIDR_Value = Stuff;
}
public string Network_Name { get; set; }
public string CIDR_Value { get; set; }
public string Broadcast_Address { get; set; }
//Deserializer - loads back from file data
//This is an overloaded function that defines the data object when it is being reconstituted
public NodeTag(SerializationInfo info, StreamingContext context)
{
Network_Name = (String)info.GetValue("Network_Name", typeof(string));
CIDR_Value = (String)info.GetValue("CIDR_Value", typeof(string));
Broadcast_Address = (String)info.GetValue("Broadcast_Address", typeof(string));
}
//Serializer - loads into file data
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("Network_Name", Network_Name);
info.AddValue("CIDR_Value", CIDR_Value);
info.AddValue("Broadcast_Address", Broadcast_Address);
}
}