如何在C#表单中拖动项目并将其放置在其他应用程序中?

4

我希望知道如何在C#中从树形视图中拖动项目并将其放置到其他(AutoCAD)应用程序中。该项目基本上是AutoCAD文件.dwg。

我已经编写了一些代码:

private void treeView1_ItemDrag(object sender, ItemDragEventArgs e)
{     

     TreeNode n = (TreeNode)e.Item;
     this.treeView1.DoDragDrop(AcadObj, DragDropEffects.Copy);

}

AcadObj是AutoCAD对象。

这个事件正常工作,但拖放事件没有触发,即使我在AutoCAD上拖动鼠标指针也会出现加号(表示文件可以在此处接受)。我的DragDrop事件如下:

private void treeview1_DragDrop(object sender, DragEventArgs e){

       MessageBox.Show("It works");
}

上述事件无法正常工作,也没有显示消息框。我只实现了这两个事件。请帮助我并指导我如何解决这个问题。
3个回答

3
问题出在内存空间上。你知道,.NET将其内存存储在CLR中。这意味着,使用.NET的拖放功能无法将任何内容从.NET拖放到运行在不同内存空间的另一个应用程序中。
你需要使用进程间拖放。
WINOLEAPI DoDragDrop( 
  IDataObject * pDataObject,  //Pointer to the data object
  IDropSource * pDropSource,  //Pointer to the source
  DWORD dwOKEffect,           //Effects allowed by the source
  DWORD * pdwEffect           //Pointer to effects on the source
);

如果你将想要拖放的对象包装在自己实现的IDataObject中,你就可以在任何应用程序中进行拖放操作。
我想提供一个例子,但是我找不到一个足够“干净”的源代码来作为示例。请在Google上搜索使用C++ COM实现的拖放操作。使用这种方法代替.NET内置的拖放操作。

3
其实,原帖没有透露所有的细节。首先,他很可能已经在同一内存空间运行,因为99%与AutoCAD相关的编程都是在进程中完成的。其次,AutoCAD的哪个版本以及.NET的哪个版本?如果不知道这两个关键数据,任何答案都可能不正确。
话虽如此,如果你把东西拖到AutoCAD中,树形视图控件上的DragDrop事件将永远不会触发——该事件仅用于树形视图上的拖放!在处理AutoCAD时,从treeview调用DoDrop也不是最佳选项。你应该调用AutoCAD应用程序的DoDragDrop事件:
AcApp.DoDragDrop(source, data, DragDropEffects.All, New DropTargetNotifier())
DropTargetNotifier会处理投放的数据,并且是你放置消息框的地方。

0
为了使您的TreeView控件能够拖放到AutoCAD绘图区域,您需要将控件托管/嵌入到AutoCAD的PaletteSet中:这是我的示例(我在此处使用ListBox即LB):
public dragdropentity TestLB; //dragdropentity is my actuall control containing my ListBox

        [CommandMethod("ListBox")]
        public void lb()
        {
            if (this.TestLB == null)
            {
                myPaletteSet = new PaletteSet("Test ListBox", new Guid("{B32639EE-05DF-4C48-ABC4-553769C67995}"));
                TestLB = new dragdropentity();
                myPaletteSet.Add("LB", TestLB);

            }
            myPaletteSet.Visible = true;
        }

一旦您能够在PaletteSet中显示TreeView,您就可以调用AutoCAD的应用程序DragDrop方法。以下是dragdropentity类中的代码段:

public partial class dragdropentity : UserControl
    {
        public dragdropentity()
        {
            InitializeComponent();
        }

        private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            //            MessageBox.Show(listBox1.SelectedIndex.ToString() + '\n' + listBox1.SelectedItem.ToString());
            pictureBox1.Load(@"D:\My\Documents\Visual Studio 2010\Projects\ClassLibrary1\ClassLibrary1\Images\" + listBox1.SelectedItem.ToString() + ".png");
        }
        void listBox1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            int indexOfItem = listBox1.IndexFromPoint(e.X, e.Y);
            if (indexOfItem >= 0 && indexOfItem < listBox1.Items.Count)  // check that an string is selected
            {
                listBox1.DoDragDrop(listBox1.Items[indexOfItem], DragDropEffects.Copy);

            }

            //           throw new System.NotImplementedException();
        }


        void listBox1_QueryContinueDrag(object sender, System.Windows.Forms.QueryContinueDragEventArgs e)
        {
            ListBox lb = (ListBox)sender;
            textBox1.AppendText('\n' + e.Action.ToString() + '\n'+ this.Name.ToString());

            if (e.Action == DragAction.Drop)
            {
                Autodesk.AutoCAD.ApplicationServices.Application.DoDragDrop(this, "Drag & drop successful!!!", System.Windows.Forms.DragDropEffects.All, new DragDrop());
            }
        }
}

DragDrop()是您自己处理“拖放事件”的类。这是我的代码:

 class DragDrop : DropTarget
    {

        public override void OnDrop(System.Windows.Forms.DragEventArgs e)
        {
            using (DocumentLock docLock = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.LockDocument())
            {
        //        MyCommands mc = new MyCommands();
          //      mc.CircleJig();

                //Call your own methods etc here.

             }

        }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接