序列化树视图时丢失数据

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);
        }
    }