允许DragDrop在表单中的任何位置

时间:2013-06-09 22:15:13

标签: c# winforms drag-and-drop

有没有办法允许在一个充满控件的表单中的任何位置拖放?

这个想法是允许用户将文件拖到表单中的任何位置以“加载”它。我不需要任何其他DragDrop行为但是这个。

通过仅将AllowDrop=True设置为表单,我会收到DragEnter个事件,但不会收到DragDrop个事件。

一个想法是在DragEnter上显示最顶层的面板并在那里处理DragDrop个事件,但我想知道我是否因为没什么经验而错过了一些明显的事情在现场。

另一个想法是迭代所有控件并订阅与Drag相关的事件。不过,我真的不喜欢这种方法。

3 个答案:

答案 0 :(得分:3)

当然,迭代控件将起作用,它不需要太多代码:

    public Form1() {
        InitializeComponent();
        WireDragDrop(this.Controls);
    }
    private void WireDragDrop(Control.ControlCollection ctls) {
        foreach (Control ctl in ctls) {
            ctl.AllowDrop = true;
            ctl.DragEnter += ctl_DragEnter;
            ctl.DragDrop += ctl_DragDrop;
            WireDragDrop(ctl.Controls);
        }
    }

    void ctl_DragDrop(object sender, DragEventArgs e) {
        // etc..
    }

    void ctl_DragEnter(object sender, DragEventArgs e) {
        // etc..
    }

如果您仍然不喜欢该方法,那么请使用用户将始终点击的可识别的单个放置目标。可以像标签“Drop here”一样简单。

答案 1 :(得分:1)

我不确定您对表单有什么样的控制权。但我已经使用Button,GroupBox,PictureBox和TextBox进行了测试。默认情况下,所有这些控件都有AllowDrop = false。而且我可以将外部的东西拖放到表单上。 DragDrop被解雇了。一切都好。你的问题到底是什么?我猜您的控件有AllowDrop = true

如果未触发DragDrop事件(我认为只有当目标是您的AllowDrop = true控件之一时才会发生)。我认为以下可能有效。但如果目标是您的AllowDrop = true控件之一,效果图标就会消失。

public Form1(){
    InitializeComponents();
    t.Interval = 1;
    t.Tick += Tick;
}
IDataObject data;
Timer t = new Timer();
int i = 0;
private void Tick(object sender, EventArgs e)
{
     Text = (i++).ToString();
     if (ClientRectangle.Contains(PointToClient(new Point(MousePosition.X, MousePosition.Y))) && MouseButtons == MouseButtons.None)
     {
        t.Stop();
        if (data != null)
        {
           //Process data here
           //-----------------               
           data = null;
        }                                
     }
     else if (MouseButtons == MouseButtons.None)
     {
        data = null;
        t.Stop();
     }
}

private void Form1_DragEnter(object sender, DragEventArgs e)
{
   e.Effect = e.AllowedEffect;
   if (data == null)
   {
       data = e.Data;
       t.Start();
   }
}

我认为您可能必须使用所有控件的循环来添加适当的事件处理程序。没有其他更好的方法。

答案 2 :(得分:-1)

Drop事件中。

string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
        foreach (string file in files) Console.WriteLine(file);

DragEnter事件中。

if (e.Data.GetDataPresent(DataFormats.FileDrop)) e.Effects = DragDropEffects.Copy;