1

有没有办法允许在充满控件的表单中的任何地方拖放?

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

通过仅设置AllowDrop=True为表单,我得到DragEnter事件而不是事件DragDrop

一个想法是让最顶层的面板可见DragEnter并在那里处理DragDrop事件,但我想知道我是否错过了一些明显的东西,因为我在该领域几乎没有经验。

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

4

3 回答 3

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”的标签一样简单。

于 2013-06-09T22:33:35.527 回答
1

我不确定您对表单有哪些类型的控制。但是我用一个按钮、一个组框、一个图片框和一个文本框进行了测试。默认情况下,所有这些控件都有AllowDrop = false。我可以从外面拖放一些东西到表格上。被DragDrop解雇了。一切都好。你的实际问题是什么?我猜你的控件有AllowDrop = true

如果DragDrop事件没有被触发(我认为只有当目标是你的 Control 之一时才会发生AllowDrop = true)。我认为以下可能有效。但是,如果目标是您的 Control 之一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();
   }
}

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

于 2013-06-10T10:01:34.760 回答
-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;
于 2013-06-09T22:20:33.783 回答