序列化树视图时丢失数据
本文关键字:数据 视图 序列化 | 更新日期: 2023-09-27 18:13:02
我正在用c#写一个程序,它将数据分配给一个类,然后将该类分配给树视图节点的标签值。
我能够序列化我的树视图文件使用一个答案我发现在这里:保存一个树视图的内容到一个文件,然后加载它。
然而,使用此方法在反序列化文件时丢失了所有节点的Tag,或者更有可能的是,它们甚至没有被序列化。
是否有可能在使用这种方法序列化时保留节点的Tag值?如果有,怎么做?
要被BinaryFormatter
成功序列化,您的Tag
对象必须标记为[Serializable]
,这表明可以通过序列化其公共和私有字段来成功序列化和反序列化。如果这样标记,那么它将序列化为TreeNode
的一部分,如参考源所示:
[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
对象不是可序列化的,它将被静默跳过;
我想改进一下这个答案。
在类之前使用[Serializable()]
和从ISerializable
派生的类是很重要的。
此外,可以接受反序列化参数的重载构造函数和 GetObjectData
函数的存在也很重要。
本质上,GetObjectData
函数为序列化程序提供了以字符串形式访问所有信息的能力,而重载的NodeTag
构造函数可以重新解释序列化的字符串数据并将其加载回对象。
[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);
}
}