怎样实现两个程序间的drag and drop, 如我写了一个程序里面有一个Tree,我运行它两次,取A&B两个进程,我想从A程序的Treeview 拖拽到B程序中的Treeview中,我用下面的代码只能在A进程(或B进程)内的TreeView内拖拽,希望高手指点迷津。            void trvLeftview_ItemDrag(object sender, ItemDragEventArgs e)
            {
                if (e.Button == MouseButtons.Right) return;  //判断是否是鼠标右键按动                this.trvLeftview.DoDragDrop(e.Item, DragDropEffects.Move);
            }            void trvLeftview_DragEnter(object sender, DragEventArgs e)
            {                    e.Effect = DragDropEffects.Move;
            }            void trvLeftview_DragDrop(object sender, DragEventArgs e)
            {
                TreeNode dragNode = (TreeNode)(e.Data.GetData(typeof(TreeNode)));                System.Drawing.Point Position = new Point();
                Position.X = e.X;
                Position.Y = e.Y;
                Position = ((TreeView)sender).PointToClient(Position);
                TreeNode targetNode = ((TreeView)sender).GetNodeAt(Position);                if (dragNode == null || targetNode == null) 
                    return;
            }

解决方案 »

  1.   

    private void treeView1_ItemDrag(object sender, System.Windows.Forms.ItemDragEventArgs e)
    {
    if((e.Item as TreeNode).Nodes.Count < 1)
    {
    this.treeView1.DoDragDrop((e.Item as TreeNode).Text, DragDropEffects.Copy);
    }
    else
    {
    MessageBox.Show("该节点不是终级节点,不能拖放!");
    }
    } private void listView1_DragDrop(object sender, System.Windows.Forms.DragEventArgs e)
    {
    string str = e.Data.GetData(typeof(string)) as string;
    list.Add(str);
    } private void listView1_DragEnter(object sender, System.Windows.Forms.DragEventArgs e)
    {
    string str = e.Data.GetData(typeof(string)) as string;
    if(list.Contains(str))
    {
    e.Effect = DragDropEffects.None;
    }
    else
    {
    e.Effect = DragDropEffects.Copy;
    }
    }
      

  2.   

    首选感谢(futurekiss2008(小林) )的CODE
    但你只能实现在一个进程里,不能在多个进程之间drag and drop.
      

  3.   

    就是普通的操作剪贴板啊
    拖拽的时候Copy进去
    然后DragDrop的时候读出来
    别忘了类型
    :)http://www.jaron.cn/chs_scripts/10/2005-03/20050311234323-101646.html
      

  4.   

    进程之间通信?你需要编写个服务器类(方法多种多样)接收A or B拖拽产生的数据,以及它要发送到的目的进程(A or B) 然后再由接收方处理.
      

  5.   

    用剪贴板问题来了,好像剪贴板的容量是有限的,我每次去取getData 都是空,private struct clipBoardData
    {
        public AbstractCPSTreeNode clipTreeNode;
        public AbstractCPSTreeNode clipParentNode;
    }clipBoardData clipboard;
    clipboard.clipTreeNode = currTreeViewNode;
    clipboard.clipTreeNode = currTreeViewNode.Parent;
    Clipboard.SetData(typeof(clipBoardData).ToString(), (object)clipboard);  object getData = Clipboard.GetDataObject().GetData(typeof(clipBoardData).ToString());
      

  6.   

    剪贴板的操作有问题
    可以看看这个例子
    http://www.codeproject.com/csharp/clipboard01.asp
      

  7.   

    你应该换一个操作的思路,不能拖动一个引用类型的对象,而是拖动值类型的对象的值.你把this.trvLeftview.DoDragDrop(e.Item, DragDropEffects.Move);
    里面的e.Item换成一个Item的关键的信息,比如Item的文本表示,或改成这样:this.trvLeftview.DoDragDrop((e.Item as TreeNode).Text, DragDropEffects.Move);然后在获取拖动内容的时候获取这个Text如下:
     string dragNode = (string)(e.Data.GetData(typeof(string)));这里应该是被拖动的节点的文本Text,然后跟据这个文本来新建立一个节点加到另一个进程的TreeView节点下.
      

  8.   

    如果你的对像要求远比一个String复杂,那么你可以写一个可序列化的类,把相关的对象的主要属性保存到这个可序列化的类的实例里,然后把这个类的实例做为拖动的对象就可以正确的得到拖动信息了.
      

  9.   

    clipBoardData 这个类必须可以序列化
    也就是必须
    [Serializable]
      

  10.   

    恩   试了一下传了个可序列化的类  就不会出现楼主开始的返回空的问题了
    不过楼主要拽的是个树 ,看来还得按照hbxtlhx(平民百姓-自已动手,丰衣足食) 提供的方法再试试哦
    我也试试呵呵
      

  11.   

    恩   试了一下传了个可序列化的类  就不会出现楼主开始的返回空的问题了
    不过楼主要拽的是个树 ,看来还得按照hbxtlhx(平民百姓-自已动手,丰衣足食) 提供的方法再试试哦
    我也试试呵呵
      

  12.   

    学习了
    这个对象可以存在任何一个地方,在硬盘的特定地方也成啊,比如存成一个xml
    处理特定的文件与处理特定的流是一样的,还不受大小复杂度的限制
      

  13.   

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.Collections;
    using System.Text.RegularExpressions;namespace WebSnatch
    {
        public partial class Form3 : Form
        {
            public Form3()
            {
                InitializeComponent();
            }        
            private void treeView1_ItemDrag(object sender, ItemDragEventArgs e)
            {
                if (e.Button == MouseButtons.Left)
                {
                    treeView1.DoDragDrop(e.Item, DragDropEffects.Move);//可去掉了
                    Clipboard.SetDataObject(new TestClass((e.Item as TreeNode).Text));
                }
            }        private void treeView1_DragEnter(object sender, DragEventArgs e)
            {
                if (e.Data.GetDataPresent(typeof(TreeNode)))
                {
                e.Effect = DragDropEffects.Move;
                }
            }        private void treeView1_DragDrop(object sender, DragEventArgs e)
            {
                TreeNode dragNode = (TreeNode)(e.Data.GetData(typeof(TreeNode)));            System.Drawing.Point Position = new Point();
                Position.X = e.X;
                Position.Y = e.Y;
                Position = ((TreeView)sender).PointToClient(Position);
                TreeNode targetNode = ((TreeView)sender).GetNodeAt(Position);            if (dragNode == null)
                    return;            // 1.目标节点不是空。2.目标节点不是被拖拽接点的字节点。3.目标节点不是被拖拽节点本身
                if (targetNode != null && targetNode.Parent != dragNode && targetNode != dragNode)
                {
                    TreeNode D = dragNode;
                    // 将被拖拽节点从原来位置删除。
                    dragNode.Remove();
                    // 在目标节点下增加被拖拽节点
                    targetNode.Nodes.Add(D);
                }
                // 如果目标节点不存在,即拖拽的位置不存在节点,那么就将被拖拽节点放在根节点之下
                if (targetNode == null)
                {
                    TreeNode D = dragNode;
                    dragNode.Remove();
                    treeView1.Nodes.Add(D);
                }
            }        private void treeView2_ItemDrag(object sender, ItemDragEventArgs e)
            {        }        private void treeView2_DragEnter(object sender, DragEventArgs e)
            {
                if (e.Data.GetDataPresent(typeof(TreeNode)))
                {
                    e.Effect = DragDropEffects.Move;
                }
            }        private void treeView2_DragDrop(object sender, DragEventArgs e)
            {
                TreeNode dragNode = new TreeNode();
                //TreeNode dragNode = (TreeNode)(e.Data.GetData(typeof(TreeNode)));
                IDataObject iData = Clipboard.GetDataObject();
                if (iData.GetDataPresent(typeof(TestClass)))
                {
                    TestClass t ;
                    t = iData.GetData(typeof(TestClass)) as TestClass;
                    dragNode = new TreeNode(t.S);
                }
                System.Drawing.Point Position = new Point();
                Position.X = e.X;
                Position.Y = e.Y;
                Position = ((TreeView)sender).PointToClient(Position);
                TreeNode targetNode = ((TreeView)sender).GetNodeAt(Position);            if (dragNode == null)
                    return;            // 1.目标节点不是空。2.目标节点不是被拖拽接点的字节点。3.目标节点不是被拖拽节点本身
                if (targetNode != null && targetNode.Parent != dragNode && targetNode != dragNode)
                {
                    TreeNode D = dragNode;
                    //// 将被拖拽节点从原来位置删除。
                    //dragNode.Remove();
                    // 在目标节点下增加被拖拽节点
                    targetNode.Nodes.Add(D);
                }
                // 如果目标节点不存在,即拖拽的位置不存在节点,那么就将被拖拽节点放在根节点之下
                if (targetNode == null)
                {
                    TreeNode D = dragNode;
                    //dragNode.Remove();
                    treeView1.Nodes.Add(D);
                }
            }
        }    [Serializable]
        public class TestClass
        {
            public TestClass(string s)
            {
                this._s = s;
            }
            private string _s;        public string S
            {
                get { return _s; }
                set { _s = value; }
            }
        }
    把上面大家的思路总结一下,试了一下,还好使呵呵。如果节点传递多少信息都可以通过TestClass传给剪贴板,其实就是序列化了,你也可以自己使用xml序列化,不过节贴板挺方便的啊,头一次用呢。这个是简单实现,很多细节都省了
      

  14.   

    只实现了第一个view往第二个拽,往回只要copy点语句就可以了
    运行两边就可以从第一个的view1往第二个的view2拽了
      

  15.   

    要用findwindow,sendmessage等api吧,要么找个中转存储的办法,比如先写到文本再读出来。
      

  16.   

    wzc999_(一流冷涧) :
    我要序列化的是一个自定义的对象,对象中包括很多成员,不仅仅是通过 new TreeView来完成的,所以我的序列化要复杂的多!是要把对象中的所以成员序列化了!
      

  17.   

    很多成员是多少啊?序列化也不受个数限制啊
    我在这里Clipboard.SetDataObject(new TestClass((e.Item as TreeNode).Text));只是演示了一个字段,如果多个的话可以new 一个比较复杂的TestClass实现那
    然后再
                if (iData.GetDataPresent(typeof(TestClass)))
                {
                    TestClass t ;
                    t = iData.GetData(typeof(TestClass)) as TestClass;
                    dragNode = new TreeNode(t.S);
                }这里把信息再给新节点就可以了
    只演示一个字段因为你再多的信息也不是所有的都用来显示啊,不行就放到Tag里得了。
    楼主把你的代码发给我试试吧