【发布时间】:2011-09-15 19:00:45
【问题描述】:
我正在开发一个大型应用程序,并正在向它添加一些拖放功能。具体来说,我允许用户将文件拖放到主窗口中以打开文件。
问题是当主窗口显示对话框时(例如,当前打开文件中的项目的属性窗口)仍然允许进行拖放操作。如果主窗口显示模式对话框,我宁愿不允许这种情况发生。这是因为在对话框打开时在应用程序中加载新文件可能会使程序崩溃:调用对话框的代码不希望在对话框打开时更改打开的文件(这就是对话框的原因是模态的......)。
主应用程序是用 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());
}
}
【问题讨论】:
-
您能否在
MyDragDrop或MyDragEnter方法开始时根据条件检查return并简单地检查是否显示对话框? -
如果我有一个函数可以确定对话框是否正在显示,那么如果有对话框,我可以在 DragEnter 事件中返回 DragDropEffects.None。但我不知道有任何这样的功能 - 如果存在用于此的 API,我很想知道它!
-
这个网站:hashfactor.wordpress.com/2009/01/28/… 是我能挖掘的全部。祝你好运!
-
这对第 3 方对话有何作用?例如,Windows 中的常见对话框(打开/保存文件、打印窗口等)。不知何故,这似乎比暂时将 AllowDrop 设置为 false 更复杂......
标签: c# c++ windows winforms drag-and-drop