无模式表单调用模态表单阻止初始表单

时间:2012-11-26 11:27:04

标签: c# .net winforms modal-dialog

我从表格A开始 表单A使用.Show()调用表单B.

因此表格A和表格B都可以访问。

现在,我不会用ShowDialog()形成B调用C表格,因为我不希望表格B在表格C打开时可以访问。

问题是:表单A无法访问。

在这种情况下,我如何才能同时访问表单A和表单C,而不是表单B?

2 个答案:

答案 0 :(得分:3)

完全按照设计,对话框会禁用应用程序中的所有窗口。这有很好的理由,在this answer中列出。

简而言之,Drastic Failure场景是用户可以使用表单A中的命令创建另一个表单B的实例,一个未禁用的实例。这允许您再次显示C,现在您显示了两个对话框。

你可能会在你的情况下永远不会发生这种情况。那没关系,但你必须撤消ShowDialog()的功能。这需要体操,你必须pinvoke 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);

您还可以在对话框的Shown事件处理程序中调用EnableWindow()调用,以避免必须使用BeginInvoke技巧。但这种方式更为普遍,对话框通常不应该是知道应用程序中其他窗口运行的业务。在这段代码中使用Form1是非常丑陋的。

答案 1 :(得分:0)

模态窗口使得用户在允许用户返回应用程序的其他部分之前需要输入和解雇。因此,如果您想让用户与多个窗口进行交互,则无法使用它们。

您必须通过在显示窗口C之前禁用窗口B(将Enabled设置为false)并在窗口C被关闭后再次启用它来手动处理此情况。