C# 显示新表单时显示的背景窗口一瞥

C# 显示新表单时显示的背景窗口一瞥,c#,.net,winforms,C#,.net,Winforms,我有主窗体。我使用form2.ShowDialog(Application.OpenForms[“Mainform”])从主窗体调用form2 然后我从form2调用另一个表单 this.Hide(); form3.ShowDialog(Application.OpenForms["MainForm"]); this.Dispose(); 一切正常,但当显示form3时,我可以瞥见背景中显示的任何窗口,即:如果我打开MS paint,将其放在背景中,则paint窗口将出

我有主窗体。我使用
form2.ShowDialog(Application.OpenForms[“Mainform”])从主窗体调用form2
然后我从form2调用另一个表单

    this.Hide();
    form3.ShowDialog(Application.OpenForms["MainForm"]);
    this.Dispose();
一切正常,但当显示form3时,我可以瞥见背景中显示的任何窗口,即:如果我打开MS paint,将其放在背景中,则paint窗口将出现在我的窗口顶部不到一秒钟,并自动转到背景。
为什么会出现这种行为。我如何纠正它?

当您调用
this.Hide()
时,Form2被隐藏,另一个窗口需要聚焦。但是,您使用ShowDialog打开了Form2,这意味着Form2是应用程序中唯一可以集中注意力的窗口。但由于隐藏了Form2,Windows会找到另一个要聚焦的窗口(在本例中为MS Paint)

解决方案的一个建议是在隐藏Form2之前人为地给予MainForm焦点:

Application.OpenForms["MainForm"].Activate();
this.Hide();
form3.ShowDialog(Application.OpenForms["MainForm"]);
this.Dispose();
也许一个更好的解决方案是首先打开Form3,等待它显示出来,然后隐藏Form2。要做到这一点,当您想显示Form3时,将此代码放在Form2中:

form3.Shown += (_s, _e) => Application.OpenForms["Form2"].Hide();
form3.ShowDialog(Application.OpenForms["MainForm"]);
this.Dispose();

好的,在显示对话框之前,您将隐藏主窗口,以便在一瞬间清楚地看到另一个窗口,以其后面的为准。你所做的也是非常危险的,你的程序失去焦点的几率非常高。无论是在显示对话框之前还是之后,您的程序都不会有一个可以接收焦点的窗口。因此,Windows窗口管理器必须找到另一个窗口以将焦点提供给它,它将选择另一个应用程序的窗口。在背景中强制你的,使它完全消失,如果窗口足够大的话

你需要采取应对措施。您可以通过延迟hide()调用来隐藏主窗口,表单的BeginInvoke()方法非常方便。您需要确保在对话框关闭之前主窗口再次可见。对话框的FormClosing事件非常方便。尽管如果对话框已连接事件而不是重写OnFormClosing(),则不是100%可靠

因此:

或者不要隐藏你的主窗口。它不是很有用,对话框已经够烦人的了,是模态的,并且阻止任何复制/粘贴。阻止用户完全看到窗口只会隐藏可能对用户有用的信息

    private void DisplayDialog_Click(object sender, EventArgs e) {
        using (var dlg = new Form2()) {
            this.BeginInvoke(new Action(() => this.Hide()));
            dlg.FormClosing += dlg_FormClosing;
            dlg.StartPosition = FormStartPosition.Manual;
            dlg.Location = this.Location;
            if (dlg.ShowDialog() == DialogResult.OK) {
                // etc..
            }
            dlg.FormClosing -= dlg_FormClosing;
        }
    }

    void dlg_FormClosing(object sender, FormClosingEventArgs e) {
        if (!e.Cancel) this.Show();
    }