问题
I am writing a program in C#, which assigns data to a class, then assigns that class to the Tag Value of treeview nodes.
I am able to serialize my treeview to file using an answer I found here: Saving content of a treeview to a file and load it later.
However, the Tag of all the nodes is lost using this method when de-serializing the file, or more likely, they are not even being serialized in the first place.
Is it possible to preserve the Tag value of the Nodes when serialized using this method? If so, how?
回答1:
To be serialized successfully by 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;
}
}
}
Note that, if your Tag
object is not serializable, it will be silently skipped; no exception will be thrown.
回答2:
I'd like to improve upon this answer.
It's important that [Serializable()]
be used before the class and that the class is derived from ISerializable
.
Additionally, the presence of the overloaded constructor function that can accept the arguments from deserialization and the GetObjectData
function were important.
In essence, the GetObjectData
function provides the ability for the serializer to access all information as a string while the overloaded NodeTag
constructor can re-interpret that serialized string data and load it back into the object.
I had to construct my class in the following fashion (this is semi-pseudo code):
[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);
}
}
来源:https://stackoverflow.com/questions/32621788/lost-data-when-serializing-treeview