【问题标题】:C# Why does form.Close() not close the form?C# 为什么 form.Close() 不关闭表单?
【发布时间】:2010-10-12 08:38:09
【问题描述】:

我有一个带有以下伪代码的按钮单击事件处理程序:

private void btnSave_Click(object sender, EventArgs e)
{
  if(txt.Text.length == 0)
     this.Close();
  else
     // Do something else

  // Some other code...
}

这只是一些简单的代码,但重点是,当文本长度为零时,我想关闭表单。但是代码不会关闭表单,而是执行部分 // 其他代码。点击事件处理程序完全执行后,表单关闭。

我知道,当我将return 放在this.Close() 之后时,表单将关闭,但我想知道为什么当您致电this.Close() 时表单没有直接关闭。为什么要执行事件处理程序的其余部分?

【问题讨论】:

    标签: c# winforms


    【解决方案1】:

    事件处理程序的其余部分被执行,因为您没有离开该方法。它是如此简单。

    调用this.Close() 不会立即“删除”表单(以及当前的事件处理程序)。如果没有更多对该表单的引用,则垃圾收集器稍后将收集该表单。

    this.Close() 只不过是一个常规的方法调用,除非该方法引发异常,否则您将停留在当前方法的上下文中。

    【讨论】:

    • 但直觉上我会在调用 this.Close() 时关闭表单,但事实并非如此。感谢您的澄清。
    • @Martijn:所以表单保持打开状态并且根本不关闭?你能展示一下“其他代码”在做什么吗?或者您可以发布一个简单的示例来展示这种行为吗?
    • @0x3a:不正确。窗体执行事件处理程序中的所有代码,然后关闭窗体。您已经回答了我的问题 :) 我想知道为什么 Close() 在调用 Close() 时不会破坏表单。
    • @martijn 调用 .Close() 时它将被关闭,但关闭不会被破坏。考虑这段代码:form.Close();释放资源();最后一个方法调用需要很长时间。你为什么希望用户看到一个无响应的表单,毕竟他们将无能为力。换句话说:有时您希望关闭表单但仍运行一些表单代码
    • @Martijn 表示表单已在视觉上关闭。它不再显示在屏幕上,并且 用户 无法与之交互。如果你关闭一个抽屉,你希望它被破坏吗?还是您只是接受必须重新打开它才能与抽屉中的内容进行交互?关闭表单也是如此。如果您希望与表单上的内容进行交互,您需要重新打开它,但就像抽屉没有被破坏一样,表单也是如此
    【解决方案2】:

    Close 只隐藏表单;表单仍然存在,如果您再次显示它,将不会收到另一个 Load 事件。

    要真正从内存中删除它,请使用 Dispose()。

    【讨论】:

    • 不,这是不正确的。 Form.Close() 将处理表单,即它调用 Dispose 方法。
    • 不完全是,如果窗体是 MDI 客户端并且不可见,则关闭不会处理。或者如果表单是一个对话框(调用 ShowDialog),它也不会 Dispose。
    • 当我使用Dispose() 而不是Close() 时,其余代码仍会执行。
    • +1。谢谢this.Dispose(); this. Close(); 对我来说很好:)
    【解决方案3】:

    答案很简单,因为您正在执行当前方法,因此 this.Close() 将被排入队列,直到您显式返回或当前执行方法抛出异常。

    【讨论】:

      【解决方案4】:

      另一种可能的解决方案是,如果您打开一个新表单并想要关闭当前表单:如果您使用 newForm.ShowDialog() 而不是 newForm.Show() 它不会使用 currentForm.Close() 关闭 currentForm,直到 newForm 也关闭.

      【讨论】:

      • 使用this.Close() 关闭表单时,请注意当前表单是否使用f.ShowDialog(); 显示,它将返回DialogResult .Cancel。在对话框(被调用者)中,我添加了this.Close(); this.Dispose(true);。现在这个对话框似乎终于要关闭了! \o/
      【解决方案5】:

      除非表单是模态表单(使用 .ShowDialog() 打开),否则 Form.Close() 也会处理表单。因此,在那之后的任何情况下,您都不能重新打开它,尽管其他人可能会说什么。这种行为有 Form.Visible(隐藏/显示表单)。

      这里的重点是 .Close() 不会从调用它的部分返回,原因有几个。例如,您可以从另一个表单或一个类或其他任何东西调用 SomeForm.Close()。

      Close() 只是一个和其他方法一样的方法。如果这是您想要的,您必须从调用 Close() 的方法中显式返回。

      【讨论】:

        【解决方案6】:

        调用 MessageBox.Show(frmMain,"a message","a title") 将表单“TextDialog”添加到应用程序的 Application.OpenForms() 表单集合中,与 frmMain 主表单本身一起。关闭消息框后它仍然存在。

        当发生这种情况并且您调用 OK 按钮委托来关闭主窗体时,调用 frmMain.Close() 将不起作用,主窗体不会消失并且程序不会像通常在您退出 OK 后那样终止代表。只有 Application.Exit() 会关闭所有垃圾消息框“TextDialog”。

        【讨论】:

          【解决方案7】:
          private void btnCloseForm_Click(object sender, EventArgs e)
          {
          FirstFrm.ActiveForm.Close();
          }
          

          如果您想关闭第一个表单并打开第二个表单,请执行以下操作:

          private void btnCloseForm_Click(object sender, EventArgs e)
          {
          FirstFrm.ActiveForm.Close();
          }
          
          private void FirstFrm_FormClosed(object sender, FormClosedEventArgs e)
          {
          SecounfFrm frm = new SecounfFrm ();
          frm.ShowDialog();
          }
          

          或者你可以这样做:

          private void btnCloseForm_Click(object sender, EventArgs e)
          {
          this.Hide();
          }
          
          private void FirstFrm_VisibleChanged(object sender, EventArgs e)
          {
          if(this.Visible == false)
          {
          this.Close();
          }
          }
          
          private void FirstFrm_FormClosed(object sender, FormClosedEventArgs e)
          {
          SecounfFrm frm = new SecounfFrm ();
          frm.ShowDialog();
          }
          

          【讨论】:

            猜你喜欢
            • 2019-12-15
            • 1970-01-01
            • 2016-10-13
            • 1970-01-01
            • 1970-01-01
            • 2014-10-03
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多