重写 Windows 窗体中的标准关闭(X)按钮

当用户单击 Windows 窗体应用程序中的 close (红色 X)按钮时(C #) ,我该如何改变发生的情况?

141750 次浏览

重写 关闭表格方法。

注意: 您需要检查 CloseReason,并且只有当它是 UserClosing 时才改变行为。你不应该在这里放任何东西,会停止 Windows 关闭例程。

WindowsVista 中应用程序关闭的更改

这是来自 Windows7徽标程序要求

这是一个很常见的问题,一个很好的答案是:

当用户单击 X (关闭程序)时,VB.NET 重载默认功能


如果您觉得把代码放在 Form _ Cclose 事件中不舒服,那么我知道的唯一其他选项是我曾经使用过一两次的“ hack”。没有必要诉诸这种黑客手段,但事实如此:


不要使用普通的关闭按钮。相反,应该创建窗体,使其没有 ControlBox。可以通过在窗体上设置 ControlBox = false 来实现这一点,在这种情况下,窗体顶部仍然有普通栏,或者可以将窗体的 FormBorderStyle 设置为“ Nothing”。如果你走这第二条路线,将没有横跨顶部的酒吧,或任何其他可见的边界,所以你将不得不模拟这些要么通过绘制的形式,或通过艺术使用面板控件。

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

您可以重写 关闭表格来执行此操作。只是要小心,不要做太出乎意料的事情,因为点击“ 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;
}
}

覆盖 关闭表格或注册事件 表格关闭

这是一个以派生形式重写 OnFormClose 函数的示例:

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

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

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

若要获得更高级的操作,请检查 FormClosingEventArgs 上的 CloseReason 属性,以确保执行适当的操作。您可能只希望在用户尝试关闭窗体时执行替代操作。

能够处理 x 按钮单击事件非常有用的一种情况是,当您使用作为 MDI 容器的 Form 时。原因在于,闭幕式和闭幕式首先是与孩子一起举行,最后是与父母一起举行。因此,在一个场景中,用户单击 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);
}

这些问题的答案缺少的一点,也是新手们可能正在寻找的一点,就是尽管举办活动是件好事:

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

除非你写 登记事件,否则它什么都不会做。把这个放到类构造函数中:

this.FormClosing += Form1_FormClosing;
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);
}

正如 Jon B 所说,但是你也需要检查一下 ApplicationExitCallTaskManagerClosing的封闭原因:

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();
}

这个被接受的答案相当有效。我使用的另一种方法是为主 Form 创建 FormCclose 方法。这和超驰装置非常相似。我的示例是一个应用程序,它在单击 Form 上的关闭按钮时最小化到系统托盘。

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

这将允许 ALT + F4或应用程序中调用 申请出口() ;的任何内容按正常方式运行,同时单击(X)将使应用程序最小化。