覆盖Windows窗体中的标准closures(X)button

如何更改用户在Windows窗体应用程序(C#中)中单击closures(红色X)button时发生的情况?

您可以重写OnFormClosing来执行此操作。 只是要小心,你不要做任何意想不到的事情,因为点击'X'closures是一个很好理解的行为。

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 Vista中的应用程序关机更改

这是来自Windows 7徽标计划的要求 。

有一件事,这些答案缺乏,哪些新手可能要找的是,虽然有一个事件是很好的:

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

除非您注册活动,否则不会做任何事情。 把这个放在类的构造函数中:

 this.FormClosing += Form1_FormClosing; 

重写OnFormClosing或注册FormClosing事件。

这是在派生forms中覆盖OnFormClosing函数的一个示例:

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

这是事件处理程序的一个例子,用于阻止表单closures,可以在任何类中进行:

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

要获得更高级的检查,请检查FormClosingEventArgs上的CloseReason属性,以确保执行相应的操作。 如果用户尝试closures表单,则可能只想执行替代操作。

就像Jon B说的那样,但是你也要检查ApplicationExitCallTaskManagerClosing 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 ?

一种情况下,能够处理xbutton单击事件是非常有用的,当您使用的是一个MDI容器的窗体。 原因在于封闭事件和封闭事件先是由孩子提出,最后是由父母提出。 因此,在一种情况下,用户单击xbuttonclosures应用程序,MDI父级要求进行确认。 如果他决定不closures申请,但继续进行任何他正在做的事情,孩子们已经处理了结束事件,可能会丢失信息/工作。 一种解决scheme是拦截主应用程序窗体中的Windows消息循环中的WM_CLOSE消息(即closures,终止应用程序),如下所示:

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

这是一个很常见的问题。 一个好的答案在这里:

当用户点击X(closures程序)时VB.NET重载默认function


如果你觉得把你的代码放在Form_Closing事件中感觉不太舒服,我唯一知道的其他select就是我曾经使用过一次或两次的“黑客”。 这不应该有必要诉诸这个黑客,但这里是:


不要使用常规closuresbutton。 相反,创build您的窗体,使其没有ControlBox。 你可以通过在窗体上设置ControlBox = false来实现这一点,在这种情况下,你仍然可以在窗体的顶部使用正常的栏,或者你可以设置窗体的FormBorderStyle为“None”,如果你走第二条路线,将不会横跨顶部或任何其他可见的边框,因此您必须通过绘制表单或通过使用Panel控件来模拟这些边框。

然后,你可以添加一个标准的button,使它看起来像一个closuresbutton,并把你的清理代码在那里。 在button事件结束时,只需调用this.Close() (C#)或Me.Close() (VB)

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

被接受的答案工作得很好。 我使用的另一种方法是为主窗体创build一个FormClosing方法。 这与覆盖非常相似。 我的例子是一个应用程序,单击窗体上的closuresbutton时最小化到系统托盘。

 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)时将正常工作,将使应用程序最小化。

  1. 只要去“Program.Designer.cs”
  2. 找出名为protected override void Dispose(bool disposing)的函数,
  3. 注释掉或删除该行的base.Dispose(disposing);
  4. 而不是那行写你的closures操作的代码