如何更改用户单击Windows Forms应用程序(在C#中)的关闭(红色X)按钮时发生的情况?
Answers:
您可以重写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;
}
}
==
重写OnFormClosing方法。
注意: 您需要检查CloseReason,并且仅当它是UserClosing时才更改行为。您不应在此处放置任何会使Windows关闭例程停止的内容。
这是来自Windows 7徽标程序的要求。
这些答案缺乏一件事,而哪些新手可能正在寻找,那就是尽管有一个活动很高兴:
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
// do something
}
除非您注册该事件,否则它什么也不会做。将其放在类构造函数中:
this.FormClosing += Form1_FormClosing;
覆盖OnFormClosing或注册事件FormClosing。
这是一个以派生形式重写OnFormClosing函数的示例:
protected override void OnFormClosing(FormClosingEventArgs e)
{
e.Cancel = true;
}
这是事件处理程序的一个示例,该事件处理程序可以阻止窗体关闭,该窗体可以在任何类中:
private void FormClosing(object sender,FormClosingEventArgs e)
{
e.Cancel = true;
}
要获得更高级的信息,请检查FormClosingEventArgs的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();
}
覆盖OnFormClosing吗?
当您使用作为MDI容器的Form时,能够处理x按钮click事件非常有用的一种情况。原因是关闭和关闭事件首先由孩子提出,最后由父母提出。因此,在一种情况下,用户单击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);
}
这是一个很常见的问题。一个很好的答案是在这里:
如果您不满意将代码放入Form_Closing事件中,那么我知道的唯一其他选择是我使用过一两次的“ hack”。不必求助于这种hack,但是这里是:
不要使用正常的关闭按钮。而是,创建您的窗体,以便它没有ControlBox。您可以通过在表单上设置ControlBox = false来执行此操作,在这种情况下,表单顶部仍将显示普通栏,或者您可以将表单的FormBorderStyle设置为“无”。将不会在顶部或任何其他可见的边框上出现横条,因此您必须通过在窗体上绘图或通过艺术使用Panel控件来模拟它们。
然后,您可以添加一个标准按钮,使其看起来像关闭按钮,然后在其中放置清理代码。在按钮事件结束时,只需调用this.Close()
(C#)或Me.Close()
(VB)
接受的答案效果很好。我使用的另一种方法是为主窗体创建一个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)时正常工作将使应用程序最小化。
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);
}