C# 覆盖 Windows 窗体中的标准关闭 (X) 按钮
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1669318/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Override standard close (X) button in a Windows Form
提问by Alex S
How do I go about changing what happens when a user clicks the close (red X) button in a Windows Forms application (in C#)?
如何更改当用户单击 Windows 窗体应用程序(在 C# 中)中的关闭(红色 X)按钮时发生的情况?
采纳答案by Jon B
You can override OnFormClosingto do this. Just be careful you don't do anything too unexpected, as clicking the 'X' to close is a well understood behavior.
您可以覆盖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;
}
}
回答by Philip Wallace
Override the OnFormClosingmethod.
覆盖OnFormClosing方法。
CAUTION:You need to check the CloseReason and only alter the behaviour if it is UserClosing. You should not put anything in here that would stall the Windows shutdown routine.
注意:您需要检查 CloseReason 并且仅在 UserClosing 时更改行为。您不应该在此处放置任何会阻止 Windows 关闭例程的内容。
Application Shutdown Changes in Windows Vista
This is from the Windows 7 logo program requirements.
这是来自Windows 7 徽标计划的要求。
回答by Ta01
Override OnFormClosing?
回答by David
This is a pretty commonly asked question. One good answer is here:
这是一个很常见的问题。一个很好的答案在这里:
VB.NET overload default functionality when user clicks the X (Close Program)
If you don't feel comfortable putting your code in the Form_Closing event, the only other option I am aware of is a "hack" that I've used once or twice. It should not be necessary to resort to this hack, but here it is:
如果您觉得将代码放入 Form_Closing 事件中感到不自在,那么我所知道的唯一其他选项是我使用过一两次的“hack”。没有必要求助于这个 hack,但这里是:
Don't use the normal close button. Instead, create your form so that it has no ControlBox. You can do this by setting ControlBox = false on the form, in which case, you will still have the normal bar across the top of the form, or you can set the form's FormBorderStyle to "None. If you go this second route, there will be no bar across the top, or any other visible border, so you'll have to simulate those either by drawing on the form, or by artistic use of Panel controls.
不要使用正常的关闭按钮。相反,创建您的表单,使其没有 ControlBox。您可以通过在表单上设置 ControlBox = false 来做到这一点,在这种情况下,您仍然会在表单顶部看到正常的栏,或者您可以将表单的 FormBorderStyle 设置为“无。如果您选择第二条路线,则有顶部将没有横条或任何其他可见边框,因此您必须通过在窗体上绘制或通过面板控件的艺术使用来模拟这些。
Then you can add a standard button and make it looklike a close button, and put your clean-up code in there. At the end of the button event, just call this.Close()
(C#) or Me.Close()
(VB)
然后你可以添加一个标准按钮,让它看起来像一个关闭按钮,然后把你的清理代码放在那里。在按钮事件结束时,只需调用this.Close()
(C#) 或Me.Close()
(VB)
回答by Chap
Either override the OnFormClosingor register for the event FormClosing.
要么覆盖OnFormClosing要么注册事件FormClosing。
This is an example of overriding the OnFormClosing function in the derived form:
这是在派生形式中覆盖 OnFormClosing 函数的示例:
protected override void OnFormClosing(FormClosingEventArgs e)
{
e.Cancel = true;
}
This is an example of the handler of the event to stop the form from closing which can be in any class:
这是阻止窗体关闭的事件处理程序的示例,它可以在任何类中:
private void FormClosing(object sender,FormClosingEventArgs e)
{
e.Cancel = true;
}
To get more advanced, check the CloseReason property on the FormClosingEventArgs to ensure the appropriate action is performed. You might want to only do the alternative action if the user tries to close the form.
要获得更高级的信息,请检查 FormClosingEventArgs 上的 CloseReason 属性以确保执行适当的操作。如果用户尝试关闭表单,您可能只想执行替代操作。
回答by Bartymaeus
One situation where it is quite useful to be able to handle the x-button click event is when you are using a Form that is an MDI container. The reason is that the closeing and closed events are raised first with children and lastly with the parent. So in one scenario a user clicks the x-button to close the application and the MDI parent asks for a confirmation to proceed. In case he decides to not close the application but carry on whatever he is doing the children will already have processed the closing event potentially lost information/work whatever. One solution is to intercept the WM_CLOSE message from the Windows message loop in your main application form (i.e. which closed, terminates the application) like so:
能够处理 x 按钮单击事件非常有用的一种情况是,当您使用作为 MDI 容器的 Form 时。原因是 close 和 closed 事件首先与孩子一起引发,最后与父母一起引发。因此,在一种情况下,用户单击 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);
}
回答by Jason Thaxter
One thing these answers lack, and which newbies are probably looking for, is that while it's nice to have an event:
这些答案缺少的一件事,以及哪些新手可能正在寻找,是虽然举办一个活动很好:
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
// do something
}
It's not going to do anything at all unless you register the event. Put this in the class constructor:
除非您注册该事件,否则它根本不会做任何事情。把它放在类构造函数中:
this.FormClosing += Form1_FormClosing;
回答by Kunal Goel
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);
}
回答by Lorenz Lo Sauer
as Jon B said, but you'll also want to check for the ApplicationExitCall
and TaskManagerClosing
CloseReason:
正如 Jon B 所说,但您还需要检查ApplicationExitCall
和TaskManagerClosing
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();
}
回答by Luke Eckley
The accepted answer works quite well. An alternative method that I have used is to create a FormClosing method for the main Form. This is very similar to the override. My example is for an application that minimizes to the system tray when clicking the close button on the Form.
接受的答案效果很好。我使用的另一种方法是为主窗体创建一个 FormClosing 方法。这与覆盖非常相似。我的例子是一个应用程序,当单击表单上的关闭按钮时,它最小化到系统托盘。
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (e.CloseReason == CloseReason.ApplicationExitCall)
{
return;
}
else
{
e.Cancel = true;
WindowState = FormWindowState.Minimized;
}
}
This will allow ALT+F4or anything in the Application calling Application.Exit();to act as normal while clicking the (X) will minimize the Application.
这将允许ALT+F4或应用程序中的任何调用Application.Exit(); 在单击 (X) 时正常操作将最小化应用程序。