C# WinForms级联模式对话框

C# WinForms级联模式对话框,c#,winforms,C#,Winforms,我有一个非常简单的WinForms应用程序,它由三个表单组成:Form1、Form2和Form3。Form1是主应用程序窗口。通过点击此窗口中的按钮,用户通过调用ShowDialog(this),以模式对话框的形式打开Form2。同样,Form2还有另一个按钮,它通过另一个调用ShowDialog(this)打开Form3。在每种情况下,此分别指向主机:Form1和Form2 在用户点击表单3中的hist OK按钮之前,一切都很好。此时,Form3和Form2模式窗口都关闭,用户返回Form1。

我有一个非常简单的WinForms应用程序,它由三个表单组成:Form1、Form2和Form3。Form1是主应用程序窗口。通过点击此窗口中的按钮,用户通过调用
ShowDialog(this)
,以模式对话框的形式打开Form2。同样,Form2还有另一个按钮,它通过另一个调用
ShowDialog(this)
打开Form3。在每种情况下,
分别指向主机:Form1和Form2

在用户点击表单3中的hist OK按钮之前,一切都很好。此时,Form3和Form2模式窗口都关闭,用户返回Form1。从逻辑上讲,用户应该返回到Form2,他或她从中启动Form3。为什么会这样?多谢各位

Form1以以下代码打开Form2:

private void form1_ButtonClick(object sender, EventArgs e)
{
    Form2 settings = new Form2();
    DialogResult result = settings.ShowDialog(this);
    if (result == DialogResult.OK)
    { }
}
然后,Form2在以下代码中打开Form3:

private void form2_ButtonClick(object sender, EventArgs e)
{
    Form3 settings = new Form3();
    DialogResult result = settings.ShowDialog(this);
    if (result == DialogResult.OK)
    { }
}
有趣的是,调试器在退出函数form2\u ButtonClick()后,下一步会立即进入form1\u ButtonClick()。我检查了处理程序的所有调用,没有看到任何与表单关闭相关的代码。即使我对我们的所有处理程序代码进行注释,表单仍然以级联的方式关闭

我怀疑表单关闭是由于分配给表单按钮的对话框结果造成的,所以我禁用了这两个按钮并添加了显式按钮处理程序。结果保持不变。另外,我注释掉了这两个函数中对话框结果的所有处理。尽管如此,关闭Form3还是会神奇地关闭其父Form2并直接进入Form1

如前所述,我还添加了显式Form2.FormClosing()处理程序,并将断点放在那里。是的,在关闭Form3时立即调用此处理程序,没有任何代码提示此调用

解决方案(部分) 由于找不到原因,我遵循了@Otterprinz的宝贵建议,并对handler进行了如下修改

private bool allowClose = true;
private void Form2_FormClosing(object sender, FormClosingEventArgs e)
{
  if (!allowClose)
  {
    e.Cancel = true;
    allowClose = true;
  }
}

在显示Form3之前,我分配
allowClose=false
。它工作并防止Form2突然关闭。我根本不知道为什么会发生这种情况。形式一点也不复杂。我仔细检查了他们的源代码,没有发现任何错误。这不是我设计的第一张,甚至不是第100张表格。以前从未见过这种效果。但是,由于你的宝贵建议,我至少找到了解决办法。谢谢大家的评论

在winform项目上进行了测试,并按预期工作。Asker的代码可能与他发布的代码不同(等价)

    // form1,form2,form3 are default forms
    // form1 button handler 
    private void button1_Click(object sender, EventArgs e)
    {
        Form2 form = new Form2();
        DialogResult result = form.ShowDialog(this);
    }

    // form2 button handler
    private void button1_Click(object sender, EventArgs e)
    {
        Form3 form = new Form3();
        DialogResult result = form.ShowDialog(this);
    }
关闭时,form3将焦点和控制权返回到form2。
Gif显示行为

如果没有真正的代码示例,我想我们只能猜测。在Form2.FormClosing上放置eventhandler并在其中放置断点。如果是您的代码执行此操作,则调用堆栈将显示。@Otterprinz,谢谢。用你的想法更新了问题文本,但没有任何效果。@Otterprinz,我倾向于接受你的解决方案,只是将“e.Cancel=true;”放入FormClosing()处理程序中。唯一的问题是要区分从哪里结束通话。如果普遍应用,原则上不可能关闭表单@BorisZinchenko我很喜欢找出原因,但我不知道你的日程安排,所以有时候“比以前更好”就足够了。
Form2 settings = new Form2();
DialogResult result = settings.ShowDialog(this);
// ShowDialog will wait settings close