如何在打开对话框时禁用拖放

时间:2011-06-15 18:29:06

标签: c# c++ windows winforms drag-and-drop

我正在开发一个大型应用程序,并为其添加了一些拖放功能。具体来说,我允许用户将文件拖放到主窗口中以打开文件。

问题是当主窗口显示对话框时(例如,当前打开文件中的项目的属性窗口),仍然允许执行拖放操作。如果主窗口显示模式对话框,我宁愿不允许这种情况发生。这是因为在对话框打开时在应用程序中加载新文件可能会导致程序崩溃:调用对话框的代码不希望在对话框打开时更改打开的文件(这就是对话框的原因)莫代尔...)。

主要应用程序是用C ++编写的,但我发布了一个C#示例。两个平台上的症状/行为都是相同的,但我可以使用C#以更少的代码来演示它。我对这两种语言/平台非常熟悉,因此我可以根据需要将任何答案翻译成适当的语言。

为了演示我的示例代码的问题,编译并运行以下C#代码。它将创建一个“主窗口”,它是一个有效的放置目标。将文件从Windows资源管理器拖放到主窗口:您应该看到“已删除”消息框。现在,单击窗体上的按钮以弹出一个对话框。再次,在对话框打开时尝试将文件拖放到主窗口上。请注意,即使打开了模式对话框,也允许删除。如何在对话框打开时防止这种情况发生?

显而易见的答案是在打开对话框时暂时将AllowDrop设置为false。问题是主应用程序非常大,因此有很多地方打开对话框。很难找到打开对话框并添加此代码的每个地方。此外,这里的每个开发人员都需要知道每次打开模态窗口时都要执行此操作;每个人都不太可能记得。我担心这不是一个很好的解决方案。

当然有一种更易于维护的方法,不需要在打开对话框的每个地方添加代码?

using System;
using System.Windows.Forms;
using System.Drawing;

public class MyDialog : Form {
    public MyDialog() {
        Text = "MyDialog";
    }
}
public class MainForm : Form {
    public MainForm() {
        Button btn = new Button();
        btn.Location = new Point(0, 0);
        btn.Text = "ShowDialog";
        btn.Size = new Size(75, 23);
        btn.Click += new EventHandler(GoToDialog);

        this.AllowDrop = true;
        this.Controls.Add(btn);
        this.Text = "Drop Target";
        this.DragDrop += new DragEventHandler(this.MyDragDrop);
        this.DragEnter += new DragEventHandler(this.MyDragEnter);
    }
    private void MyDragDrop(object sender, DragEventArgs e) {
        MessageBox.Show("dropped");
    }
    private void MyDragEnter(object sender, DragEventArgs e) {
        e.Effect = DragDropEffects.Copy;
    }
    private void GoToDialog(object sender, EventArgs e) {
        using (MyDialog ab = new MyDialog()) {
            ab.ShowDialog(this);
        }
    }
}
static class Program {
    [STAThread]
    static void Main() {
        Application.Run(new MainForm());
    }
}

1 个答案:

答案 0 :(得分:2)

我不确定C#中的工作原理如何,所以如果这个答案不正确,请告诉我。在C ++ MFC中,当显示对话框时,将禁用主窗口。您可以测试是否禁用主窗口,如果是,则忽略掉落。

private void MyDragDrop(object sender, DragEventArgs e) {
    if (CanFocus)
        MessageBox.Show("dropped");
}
private void MyDragEnter(object sender, DragEventArgs e) {
    if (CanFocus)
        e.Effect = DragDropEffects.Copy;
    else
        e.Effect = DragDropEffects.None;
}