一、问题描述:做IDE开发经常会遇到这样一种情况:使用者开两个应用程序,把一个应用程序中的控件copy到另一个应用程序中。
这样做只是用户的一个使用小细节便于使用者对比刻制,我们如果能抓住这些细节,那么我们的产品客户体验度会上一个层次。
二、解决思路:跨应用程序copy,也可以说是两个单独的进程间通信。两个进程间的通信大概有以下几种:剪贴板Clipboard、窗
口消息、使用共享内存、动态数据交换、消息管道(有匿名通道、命名通道)、邮件槽、套接字、internet、RPC(远程过程调用)、串
行并行通信、COM/DCOM等。当前采用剪切板的方式。
原理如下:在copy端,把要copy的数据写到剪切板中,在pase端,在剪切板中取出对应类型的数据。
三、解决方案:开始以为:按照上面说的原理,把控件写到剪切板中不就ok。范例如下:
copy端:
TreeNode t = new TreeNode("ClipBoardNode");
Clipboard.SetData("TreeNode", t);
pase端:
TreeNode t = (TreeNode)Clipboard.GetData("TreeNode");
if (treeView1.SelectedNode == null) treeView1.Nodes.Add(t); else treeView1.SelectedNode.Nodes.Add(t);
可是一运行出现当机:error信息大致是:TreeNode 不可以序列化。
原来:对于控件是不可以直接写到剪切板中的,写到剪切板中的数据必须是以流的形式。而上面,控件是不可以直接序列化成流的。
新的解决方案:
需要写个单独的方法,对控件做序列化处理后,才能写到剪切板中。
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; }
然后:copy端:
TreeNode t = new TreeNode("ClipBoardNode");
Clipboard.SetData("TreeNode", Serialize(t));
pase端:
TreeNode t = (TreeNode)DeSerialize(Clipboard.GetData("TreeNode").ToString());
if (treeView1.SelectedNode == null) treeView1.Nodes.Add(t); else treeView1.SelectedNode.Nodes.Add(t);