【问题标题】:Detect reason for form closing检测表单关闭的原因
【发布时间】:2014-05-02 09:47:27
【问题描述】:

如何检测窗口窗体是如何关闭的?例如,如何确定用户是否单击了关闭表单的按钮,或者用户是否单击了右上角的“X”?谢谢。

更新:

忘了说按钮调用了 Application.Exit() 方法。

【问题讨论】:

标签: c# winforms


【解决方案1】:

正如 bashmohandes 和 Dmitriy Matveev 已经提到的,解决方案应该是 FormClosingEventArgs。但正如 Dmitriy 所说,这不会对您的按钮和右上角的 X 产生任何影响。

要区分这两个选项,您可以在表单中添加一个布尔属性 ExitButtonClicked,并在调用 Application.Exit() 之前在按钮 Click-Event 中将其设置为 true。 p>

现在您可以在 FormClosing 事件中询问此属性,并在案例 UserClosing 中区分这两个选项。

例子:

    public bool UserClosing { get; set; }

    public FormMain()
    {
        InitializeComponent();

        UserClosing = false;
        this.buttonExit.Click += new EventHandler(buttonExit_Click);
        this.FormClosing += new FormClosingEventHandler(Form1_FormClosing);
    }

    void buttonExit_Click(object sender, EventArgs e)
    {
        UserClosing = true;
        this.Close();
    }

    void Form1_FormClosing(object sender, FormClosingEventArgs e)
    {
        switch (e.CloseReason)
        {
            case CloseReason.ApplicationExitCall:
                break;
            case CloseReason.FormOwnerClosing:
                break;
            case CloseReason.MdiFormClosing:
                break;
            case CloseReason.None:
                break;
            case CloseReason.TaskManagerClosing:
                break;
            case CloseReason.UserClosing:
                if (UserClosing)
                {
                    //what should happen if the user hitted the button?
                }
                else
                {
                    //what should happen if the user hitted the x in the upper right corner?
                }
                break;
            case CloseReason.WindowsShutDown:
                break;
            default:
                break;
        }

        // Set it back to false, just for the case e.Cancel was set to true
        // and the closing was aborted.
        UserClosing = false;
    }

【讨论】:

  • 奥利弗,你现在犯了严重的错误。如果您在关闭原因为 CloseReason.ApplicationExitCall 并且 if(UserClosing) 条件将无用时从单击处理程序调用 Application.Exit。您应该在单击处理程序中调用 this.Close() 方法以匹配 UserClosing 开关情况,或者您需要将 if 语句移到 switch 语句的外部。
  • 如果表单在您进入 Form1_FormClosing 时从未关闭——也许有一个“您是否打算退出?”问题 - 需要将 UserClosing 标志变量设置为 false 或者下次它可能错误地为 true。
  • 最简单的方法是将“正常”关闭按钮的 DialogResult 属性设置为 None 以外的值。在 Form_Closing 中,您可以检查这些结果并假设 DialogResult.None 是表单控制框中的“X”按钮。微软的一种愚蠢的实现是没有对内置的“X”按钮进行特定处理。
【解决方案2】:

您可以在 FormClosing 事件处理程序中检查 FormClosingEventArgs 的 CloseReason 属性以检查一些可能的情况。但是,如果您只使用此属性,您描述的情况将无法区分。您需要在“关闭”按钮的单击事件处理程序中编写一些额外的代码来存储一些信息,这些信息将在 FormClosing 事件处理程序中检查以区分这些情况。

【讨论】:

    【解决方案3】:

    您需要向 Even FormClosing 添加一个侦听器,它会在事件 args 中发送一个 CloseReason 类型的属性,该属性是这些值之一

        // Summary:
    //     Specifies the reason that a form was closed.
    public enum CloseReason
    {
        // Summary:
        //     The cause of the closure was not defined or could not be determined.
        None = 0,
        //
        // Summary:
        //     The operating system is closing all applications before shutting down.
        WindowsShutDown = 1,
        //
        // Summary:
        //     The parent form of this multiple document interface (MDI) form is closing.
        MdiFormClosing = 2,
        //
        // Summary:
        //     The user is closing the form through the user interface (UI), for example
        //     by clicking the Close button on the form window, selecting Close from the
        //     window's control menu, or pressing ALT+F4.
        UserClosing = 3,
        //
        // Summary:
        //     The Microsoft Windows Task Manager is closing the application.
        TaskManagerClosing = 4,
        //
        // Summary:
        //     The owner form is closing.
        FormOwnerClosing = 5,
        //
        // Summary:
        //     The System.Windows.Forms.Application.Exit() method of the System.Windows.Forms.Application
        //     class was invoked.
        ApplicationExitCall = 6,
    }
    

    【讨论】:

    • Nate 描述的这两种情况都是 CloseReason.UserClosing,那么这个属性的使用对他有什么帮助呢?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-12
    • 2012-07-25
    • 2014-02-06
    • 2020-03-21
    • 1970-01-01
    相关资源
    最近更新 更多