【问题标题】:Form.Close() doesn't close window immediatelyForm.Close() 不会立即关闭窗口
【发布时间】:2011-08-18 07:03:22
【问题描述】:

如果我用户以某种方式关闭主表单,我需要确保所有表单都将关闭。所以我决定隐藏 Close() 函数,我写了这样的东西

public new bool Close()
        {
            List<Form> formsList = new List<Form>(Application.OpenForms.Count);
            foreach (var form in Application.OpenForms)
                formsList.Add((Form)form);
            formsList.Reverse();
            foreach (var form in formsList)
            {
                if (form.IsDisposed) continue;
                Invoke(new GenericEventHandler(() => { form.Close(); }));
            }

            return Application.OpenForms.Count == 0;
        }

所以如果所有表单都成功关闭,我会返回 true,因此我知道用户可以从应用程序中注销。

但是,form.Close() 函数似乎没有立即触发。调用form.Close() formclosed 事件后不会立即触发,集合 Application.OpenForms 也不会被修改。已打开表单的数量已更改。

可能是什么原因?

【问题讨论】:

    标签: c# winforms


    【解决方案1】:

    你为什么不直接使用

    Application.Exit();
    

    【讨论】:

    • 因为某些表单在没有确认或用户操作的情况下无法关闭
    • @geronimo:但是在您上面提到的代码中,我没有看到您正在确认任何用户操作。
    • 在表单关闭事件期间调用确认。我只是忘了提及它:)
    【解决方案2】:

    如果主窗体是通过Application.Run(new MainForm()); 在 WinForms 中以标准方式创建的,那么当它关闭时,应用程序将退出,并关闭所有其他窗体。所以我认为您不必担心手动关闭所有子表单。

    【讨论】:

      【解决方案3】:

      好吧,如果用户关闭了主窗体,那么在关闭它时,您的应用程序肯定会退出,因为您的窗体在传递给 Application.Run() 时负责保持应用程序处于活动状态.

      现在,如果您想在 a 表单关闭时关闭您的应用,请在该表单中执行以下操作:

      protected override void OnFormClosed(FormClosedEventArgs e)
      {
          base.OnFormClosed(e);
          Application.Exit();
      }
      

      【讨论】:

        【解决方案4】:

        一般来说,我建议不要对 Control 和/或 Form 类的任何成员使用 new 关键字。如果您需要自己的方法,请使用您自己的名称。

        在您的代码中,您在关闭子表单时实际上并不需要使用 Invoke。

        如果您需要确保在实际执行与 MainForm.Close 相关的逻辑之前关闭所有子窗体,您可以使用类似于以下的处理程序订阅 MainForm.FormClosing 事件:

        void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            bool allChildFormsClosed = !closeAllChildForms();
        
            if(!allChildFormsClosed)
            {
                e.Cancel = true;
                MessageBox.Show("Failed to close one or more child forms.");
                // better add some yes|no dialog to force exit if necessary
            }
        }
        

        您可以用与上面类似的方式实现 closeAllChildForms - 只是:删除 formsList.Reverse();和 'Invoke..' - 只需直接调用 Close 并更新: if (this == form || form.IsDisposed) continue;

        【讨论】:

          【解决方案5】:

          如果由于某种原因 Application.Exit 没有为您解决问题,您可以尝试以下代码(将其放入表单的 FormClosing 事件中):

          while (Application.OpenForms.Count > 1)
          {
            Form form = Application.OpenForms[1];
            form.Close();
            while (!form.IsDisposed) Application.DoEvents();
          }
          

          或者如果您希望它在一段时间后无法关闭所有表单时超时,

          while (Application.OpenForms.Count > 1)
          {
            Form form = Application.OpenForms[1];
            form.Close();
            DateTime StartTime = DateTime.Now;
            while (!form.IsDisposed && (StartTime - DateTime.Now).TotalMilliseconds < 1000)
              Application.DoEvents(); //1-second timeout here
            if (!form.IsDisposed) //if it's still not closed
            {
              //send a message to the user that the application can't exit right now
              mbox("some forms are still open or whatever");
              e.Cancel = true;
              return;
            }
          }
          

          【讨论】:

            猜你喜欢
            • 2020-11-08
            • 2021-05-12
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-02-24
            相关资源
            最近更新 更多