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

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

最佳答案

我不确定在 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;
} 

关于c# - 如何在对话框打开时禁用拖放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6362517/

相关文章:

windows - 等待程序加载 DLL,然后挂起它

c# - 如何删除某个扩展名的文件?

c# - 将联合查询转换为 LINQ 到实体查询

c++ - 链接来自另一个文件的函数时,Qt 上的错误 LNK 2019

windows - IBM API 的 Python 多处理错误(Q Experience)

c# - 如何在用户不首先关注文本框的情况下读取条形码?

c# - 为什么这个字符串扩展方法没有抛出异常?

c# - 安装没有模板的服务

python - 自更新到 Xcode 7.3 以来导入 gensim 失败

c# - 递归循环 (C#)