我从表格 A 开始。表格 A 用.
调用表格 B。.Show()
所以表格 A 和表格 B 都可以访问。
现在,我不想用 表单 B 调用表单 C ShowDialog()
,因为我不想在表单 C 打开时访问表单 B。
问题是:表格 A 无法访问。
在这种情况下,我怎样才能同时访问表单 A 和表单 C,但不能访问表单 B?
我从表格 A 开始。表格 A 用.
调用表格 B。.Show()
所以表格 A 和表格 B 都可以访问。
现在,我不想用 表单 B 调用表单 C ShowDialog()
,因为我不想在表单 C 打开时访问表单 B。
问题是:表格 A 无法访问。
在这种情况下,我怎样才能同时访问表单 A 和表单 C,但不能访问表单 B?
这完全是设计使然,对话框会禁用应用程序中的所有窗口。这个答案中概述了一个很好的理由。
简而言之,Drastic Failure 场景是用户可以使用表单 A 中的命令创建表单 B 的另一个实例,该实例未被禁用。它允许您再次显示 C,现在您有两个对话框显示。
你可能会说这在你的情况下永远不会发生。没关系,但是您必须撤消 ShowDialog() 所做的事情。这需要体操,您必须调用 EnableWindow() 以重新启用表单 A 实例。但是您必须在 ShowDialog() 调用之后但在它结束之前这样做。您可以通过在 UI 线程上使用 Control.BeginInvoke() 来执行某些操作。魔术师看起来像这样:
private void ShowDialogButton_Click(object sender, EventArgs e) {
using (var dlg = new Form3()) {
// Find the main form instance
var main = Application.OpenForms.OfType<Form1>().Single();
this.BeginInvoke(new Action(() => {
EnableWindow(main.Handle, true);
}));
if (dlg.ShowDialog(this) == DialogResult.OK) {
// etc..
}
}
}
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern bool EnableWindow(IntPtr handle, bool enable);
您还可以将 EnableWindow() 调用放在对话框的 Shown 事件处理程序中,从而避免使用 BeginInvoke 技巧。但是这种方式更通用,对话框通常不应该用于了解应用程序中运行的其他窗口。在这段代码中使用 Form1 已经够难看的了。
模态窗口是这样的,它们需要用户输入和关闭,然后才允许她返回到应用程序的其他部分。因此,如果您想让用户与多个窗口进行交互,则不能使用它们。
您必须手动处理这种情况,方法是在显示窗口 C 之前禁用窗口 B(设置Enabled
为false
),并在关闭窗口 C 后再次启用它。