覆盖Windows窗体中的标准关闭(X)按钮

时间:2009-11-03 18:37:46

标签: c# winforms

如何更改用户单击Windows窗体应用程序中的关闭(红色X)按钮(在C#中)时发生的情况?

11 个答案:

答案 0 :(得分:125)

您可以覆盖OnFormClosing来执行此操作。请注意,不要做任何太意外的事情,因为单击“X”关闭是一个很好理解的行为。

protected override void OnFormClosing(FormClosingEventArgs e)
{
    base.OnFormClosing(e);

    if (e.CloseReason == CloseReason.WindowsShutDown) return;

    // Confirm user wants to close
    switch (MessageBox.Show(this, "Are you sure you want to close?", "Closing", MessageBoxButtons.YesNo))
    {
    case DialogResult.No:
        e.Cancel = true;
        break;
    default:
        break;
    }        
}

答案 1 :(得分:18)

覆盖OnFormClosing方法。

注意:您需要检查CloseReason并仅在UserClosing时更改行为。你不应该在这里放任何会阻碍Windows关闭程序的东西。

Application Shutdown Changes in Windows Vista

这来自Windows 7 logo program requirements

答案 2 :(得分:17)

这些答案缺乏的一件事,以及新手们可能正在寻找的是,虽然举办活动很有意义:

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    // do something
}

除非你register the event,否则根本不会做任何事情。把它放在类构造函数中:

this.FormClosing += Form1_FormClosing;

答案 3 :(得分:10)

覆盖OnFormClosing或注册活动FormClosing

这是在派生形式中覆盖OnFormClosing函数的示例:

protected override void OnFormClosing(FormClosingEventArgs e)
{
   e.Cancel = true;
}

这是阻止表单关闭的事件处理程序的一个示例,它可以在任何类中:

private void FormClosing(object sender,FormClosingEventArgs e)
{  
   e.Cancel = true;
}

要获得更高级的功能,请检查FormClosingEventArgs上的CloseReason属性,以确保执行适当的操作。如果用户尝试关闭表单,您可能只想执行备用操作。

答案 4 :(得分:7)

如Jon B所说,但你也想检查ApplicationExitCallTaskManagerClosing CloseReason:

protected override void OnFormClosing(FormClosingEventArgs e)
{
    if (  e.CloseReason == CloseReason.WindowsShutDown 
        ||e.CloseReason == CloseReason.ApplicationExitCall
        ||e.CloseReason == CloseReason.TaskManagerClosing) { 
       return; 
    }
    e.Cancel = true;
    //assuming you want the close-button to only hide the form, 
    //and are overriding the form's OnFormClosing method:
    this.Hide();
}

答案 5 :(得分:3)

覆盖OnFormClosing

答案 6 :(得分:3)

当您使用作为MDI容器的Form时,能够处理x按钮单击事件非常有用的一种情况。原因是关闭和关闭事件首先是与孩子一起提出的,最后是与父母一起提出的。因此,在一种情况下,用户单击x按钮以关闭应用程序,MDI父级要求确认继续。如果他决定不关闭申请但继续他正在做的事情,孩子们已经处理了结束事件可能丢失的信息/工作无论如何。 一种解决方案是拦截主应用程序表单中Windows消息循环中的WM_CLOSE消息(即关闭,终止应用程序),如下所示:

    protected override void WndProc(ref Message m)
    {
        if (m.Msg == 0x0010) // WM_CLOSE
        {
            // If we don't want to close this window 
            if (ShowConfirmation("Are you sure?") != DialogResult.Yes) return;
        }

        base.WndProc(ref m);
    }

答案 7 :(得分:1)

这是一个非常常见的问题。一个很好的答案在这里:

VB.NET overload default functionality when user clicks the X (Close Program)


如果您觉得将代码放在Form_Closing事件中感觉不舒服,我所知道的唯一其他选项就是我曾经使用过一次或两次的“hack”。没有必要诉诸这个黑客,但这里是:


请勿使用常规关闭按钮。而是创建您的表单,使其没有ControlBox。你可以通过在窗体上设置ControlBox = false来做到这一点,在这种情况下,你仍然可以在窗体的顶部有一个普通的条,或者你可以将窗体的FormBorderStyle设置为“None。如果你去第二条路线,那里在顶部或任何其他可见边框上都没有条形图,因此您必须通过在表单上绘图或通过艺术使用Panel控件来模拟它们。

然后你可以添加一个标准按钮并将其作为关闭按钮 ,并将清理代码放在那里。在按钮事件结束时,只需调用this.Close()(C#)或Me.Close()(VB)

答案 8 :(得分:0)

protected override bool ProcessCmdKey(ref Message msg, Keys dataKey)
    {
        if (dataKey == Keys.Escape)
        {
            this.Close();
            //this.Visible = false;
            //Plus clear values from form, if Visible false.
        }
        return base.ProcessCmdKey(ref msg, dataKey);
    }

答案 9 :(得分:0)

接受的答案非常有效。我使用的另一种方法是为主Form创建FormClosing方法。这与覆盖非常相似。我的示例是单击表单上的关闭按钮时最小化到系统托盘的应用程序。

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    {
        if (e.CloseReason == CloseReason.ApplicationExitCall)
        {
            return;
        }
        else
        {
            e.Cancel = true;
            WindowState = FormWindowState.Minimized;
        }            
    }

这将允许 ALT + F4 或应用程序中调用 Application.Exit(); 的任何内容正常运行,而单击(X)将最小化应用程序。

答案 10 :(得分:-4)

  1. 只需转到“Program.Designer.cs”
  2. 即可
  3. 找出名为protected override void Dispose(bool disposing)
  4. 的函数
  5. 注释掉或删除第base.Dispose(disposing);
  6. 而不是该行为您的关闭操作编写代码