如何更改用户单击Windows窗体应用程序中的关闭(红色X)按钮(在C#中)时发生的情况?
答案 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关闭程序的东西。
答案 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)
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();
}
答案 5 :(得分:3)
答案 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)
protected override void Dispose(bool disposing)
base.Dispose(disposing);
行