一、問題描述:做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);