要存储一个类型,序列化是最简单的一种实现方式,TreeView本省并不支持序列化,但是TreeNode支持,因此需要从TreeNode下手, 所有序列化TreeView其实就是序列化TreeNode.
1. 自定义一个类SerialzeTreeNode继承TreeNode继承并实现ISerializable接口,其实TreeNode已经实现了ISerializable接口,在实现这个接口时要调用基类TreeNode的Serialize函数,要不然序列化的节点会不全,在Serialize函数中添加自己的序列化逻辑,
3. 有可能的话实现一个IDeserializationCallback接口,以便于在反序列化后初始化一些变量之类的动作,因为,反序列化只调用反序列化的那个构造函数.
4. 添加泛型支持,其实也可以用Tag用来存储要序列化的值,但是Tag是object的,不是很好,因此增加一个泛型
变量是很有意义的,这样便于强化类型也能够很好的利用IDE的智能感知功能.
public class SerializTreeNode<T>:TreeNode,ISerializable
{
public T TTag;
}
5. 如果要使用小图标的话还要做些工作,虽然查看反序列化中的数据,有ImageSelectedIndex项,但是却无效,因此在实现ISerializable接口中顺便把ImageSelectedIndex属性也序列化进去,然后在反序列化的时候设置其值,这样就可以保存其图片索引了.Key与Index冲突,只能一个有效,因此可以二选一,看TreeView是如何设置图片的了.
6. 对自定义类加上Serializable可序列化标记,要不然都正确了还是无法正确工作的.,同时泛型的那个类也必须要标记为Serializable,否则也会出错.
7. 扩展TreeView提供序列化和反序列化的函数以保存树节点和加载保存的树节点.
public interface ISerializeTreeView
{
bool SaveTreeView(string filename);
bool LoadTreeView(string filename);
}
可以定义这样的一个接口
二:拷贝对象到剪切板
Add object to Clipboard using C# in a couple of ways
This is a simple example of using the ClipBoard to transport objects. In this example I will generate a TreeNode and save it to a ClipBoard entry. I will then retrieve this node, cast it and either add it to the root of the TreeView or add it to the selected node's child nodes.
Method 1
Step 1: Copy new TreeNode to Clipboard
private void button1_Click(object sender, EventArgs e)
{
TreeNode t = new TreeNode("ClipBoardNode");
Clipboard.SetData("TreeNode", t);
}
Step 2: Paste new TreeNode from Clipboard to TreeView
private void button2_Click(object sender, EventArgs e)
{
TreeNode t = (TreeNode)Clipboard.GetData("TreeNode");
if (treeView1.SelectedNode == null)
treeView1.Nodes.Add(t);
else
treeView1.SelectedNode.Nodes.Add(t);
}
Method 2
Another way to append to the Clipboard is the method SetDataObject and GetDataObject. There is however some difference here.
You do not provide a key, you simply save it to a designated location
You are limited to the objects which you cast the returned object back into as you can see from the image below.
To solve this I made two simple helper methods which would serialize the object to a binary representation and then get the base64String of that data, thus giving me a string object. I then put this into the ClipBoard and going the other way I did the opposite. Converted the base64String into a byte array, instantiated a MemoryStream with it and then deserialized the data returning an object. It is then up to the calling code to cast the object.
The helper methods
private string Serialize(object objectToSerialize)
{
string serialString = null;
using (System.IO.MemoryStream ms1 = new System.IO.MemoryStream())
{
BinaryFormatter b = new BinaryFormatter();
b.Serialize(ms1, objectToSerialize);
byte[] arrayByte = ms1.ToArray();
serialString = Convert.ToBase64String(arrayByte);
}
return serialString;
}
private object DeSerialize(string serializationString)
{
object deserialObject = null;
byte[] arrayByte = Convert.FromBase64String(serializationString);
using (System.IO.MemoryStream ms1 = new System.IO.MemoryStream(arrayByte))
{
BinaryFormatter b = new BinaryFormatter();
deserialObject = b.Deserialize(ms1);
}
return deserialObject;
}
Method Code 2 Steps
Step 1: Copy new TreeNode to Clipboard
private void button1_Click_1(object sender, EventArgs e)
{
TreeNode t = new TreeNode("ClipBoardNode");
Clipboard.SetData("TreeNode", Serialize(t));
}
Step 2: Paste new TreeNode from Clipboard to TreeView
private void button2_Click(object sender, EventArgs e)
{
TreeNode t = (TreeNode)DeSerialize(Clipboard.GetData("TreeNode").ToString());
if (treeView1.SelectedNode == null)
treeView1.Nodes.Add(t);
else
treeView1.SelectedNode.Nodes.Add(t);
}