当用户在Windows窗体应用程序中单击关闭(红色X)按钮时,我该如何更改其操作(使用C#语言编写)?
您可以重写 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();
}
在处理MDI容器的窗体时,处理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);
}
这是一个非常常见的问题。这里有一个不错的答案:
如果您不喜欢将代码放在Form_Closing事件中,我只知道另一个选项就是使用一种我曾经用过一两次的“hack”。虽然不应该必须采用这种hack,但我还是给出了以下方法:
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 void OnFormClosing(FormClosingEventArgs e)
{
Environment.Exit(0);
}