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

How to disable drag/drop when a dialog box is open(如何在打开对话框时禁用拖放)
本文介绍了如何在打开对话框时禁用拖放的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

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

I am working on a large application and am adding some drag/drop functionality to it. Specifically, I am allowing the user to drag and drop a file into the main window to open the file.

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

The problem is that the drag/drop operation is still allowed to happen when the main window is displaying a dialog box (for example, a properties window for an item in the currently-open file). I would rather not allow this to happen if the main window is displaying a modal dialog box. This is because loading the new file in the application while the dialog box is open would probably crash the program: the code calling the dialog box does not expect the open file to be changed while the dialog box is open (that is why the dialog box was modal...).

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

The main application is written in C++, but I am posting a C# sample. The symptom/behavior is the same on both platforms, but I can demonstrate it in much less code with C#. I am very familiar with both languages/platforms so I can translate any answers to the appropriate language as needed.

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

To demonstrate the problem with my sample code, compile and run the following C# code. It will create a "main window" that is a valid drop target. Drag and drop a file from Windows Explorer onto the main window: you should see a "dropped" message box. Now, click the button on the form to pop up a dialog box. Again, attempt to drag and drop a file onto the main window while the dialog box is open. Notice that the drop is allowed even though a modal dialog box is open. How can I prevent this from happening when the dialog is open?

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

The obvious answer is to temporarily set AllowDrop to false while opening the dialog box. The problem is that the main application is very large and so there are numerous places that open dialog boxes. It will be difficult to find every single place that opens a dialog and add this code. Plus, every developer here would need to know to perform this action every time they open a modal window; it is unlikely that everyone will remember. I am worried that this is not a very good solution.

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

Surely there is a more maintainable method of doing this that doesn't require adding code in every place that a dialog is opened?

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 中,显示对话框时禁用主窗口.你可以测试看看主窗口是否被禁用,如果是则忽略drop.

I'm not sure how things work in C#, so let me know if this answer is incorrect. In C++ MFC, the main window is disabled when a dialog is displayed. You can test to see if the main window is disabled and ignore the drop if so.

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

这篇关于如何在打开对话框时禁用拖放的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

相关文档推荐

Force JsonConvert.SerializeXmlNode to serialize node value as an Integer or a Boolean(强制 JsonConvert.SerializeXmlNode 将节点值序列化为整数或布尔值)
Using JSON to Serialize/Deserialize TimeSpan(使用 JSON 序列化/反序列化 TimeSpan)
Could not determine JSON object type for type quot;Classquot;(无法确定类型“Class的 JSON 对象类型.)
How to deserialize a JSONP response (preferably with JsonTextReader and not a string)?(如何反序列化 JSONP 响应(最好使用 JsonTextReader 而不是字符串)?)
how to de-serialize JSON data in which Timestamp it-self contains fields?(如何反序列化时间戳本身包含字段的JSON数据?)
JSON.Net custom contract serialization and Collections(JSON.Net 自定义合约序列化和集合)