Allow DragDrop anywhere in a form

心已入冬 提交于 2019-12-11 12:28:59

问题


Is there a way to allow Drag and Drop anywhere in a form full of controls?

The idea is to allow user to drag a file anywhere in a form in order to "load" it. I will not need any other DragDrop behavior but this.

By setting AllowDrop=True to the form only, I get DragEnter events but not DragDrop ones.

An idea would be to make a topmost panel visible on DragEnter and handle DragDrop events there, but I wonder if I miss something obvious here since I have little experience in the field.

Another Idea would be to iterate through all controls and subscribe to Drag-related events. I really don't like this approach, though.


回答1:


Sure, iterating the controls will work, it doesn't take much code:

    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..
    }

If you still don't like the approach then use a recognizable single drop target that the user will always hit. Could be as simple as a label that says "Drop here".




回答2:


I'm not sure what kinds of control you have on your form. But I've tested with a Button, a GroupBox, a PictureBox and a TextBox. All these controls have AllowDrop = false by default. And I can drag-n-drop something from outside onto the form OK. The DragDrop is fired OK. Everything is OK. What is actually your problem? I guess your controls have AllowDrop = true.

In the case the DragDrop event is not fired (which I think only happens if the target is one of your Control with AllowDrop = true). I think the following may work. But if the target is one of your Control with AllowDrop = true, the effect icon is gone away.

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();
   }
}

And I think you may have to use the loop through all the Controls to add appropriate event handlers. There is no other better way.




回答3:


In the Drop event.

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

In the DragEnter event.

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


来源:https://stackoverflow.com/questions/17014700/allow-dragdrop-anywhere-in-a-form

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!