如何禁用Alt + F4关闭表格?


78

停用Alt+的最佳方法是什么F4在ac#win表单中以防止用户关闭表单?

我正在使用窗体作为弹出对话框来显示进度条,但我不希望用户能够将其关闭。


在FormClosing事件处理程序中,您是否可以询问键盘缓冲区(您是否甚至可以访问此缓冲区?)以检查是否按下了[Alt] + [F4],如果是,则取消,否则,是否继续?
传统知识。

Answers:


106

这可以做到:

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

编辑:响应pix0rs的问题-是的,您是正确的,您将无法以编程方式关闭该应用程序。但是,您可以在关闭表单之前简单地删除form_closing事件的事件处理程序:

this.FormClosing -= new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing);
this.Close();

4
我怀疑大多数人都在有问题的表单(Form1)上实现此方法。在这种情况下,建议您不要附加委托,而应重写OnFormClosing方法。“ OnFormClosing方法还允许派生类在不附加委托的情况下处理事件。这是在派生类中处理事件的首选技术。” tinyurl.com/3dzzljq
antsawn

9
我本可以将事件处理程序设为:e.Cancel = (e.Reason == CloseReason.UserClosing);。这样,您可以保证仅在USER尝试关闭表单时不会关闭。
Paulo Santos,

这种方法有一个大问题:如果您想关闭/重新启动PC,它也会取消该请求(至少在Windows XP上如此)
conceptacid 2014年

太精彩了!当您要关闭表单时,我特别喜欢删除该事件。非常简单!!!
2014年

@Will:我已经编辑了答案。现在有一个无需删除事件处理程序即可运行的解决方案。
Thomas Weller

59

如果你看一下价值FormClosingEventArgs e.CloseReason,它会告诉你为什么形式正在被关闭。然后,您可以决定要做什么,可能的值为:

会员名称-说明


-未确定关闭原因或无法确定关闭原因。

WindowsShutDown-操作系统在关闭之前将关闭所有应用程序。

MdiFormClosing-此多文档接口(MDI)表单的父表单正在关闭。

UserClosing-用户通过用户界面(UI)关闭表单,例如,单击表单窗口上的“关闭”按钮,从窗口的控制菜单中选择“关闭”,或按ALT+ F4

TaskManagerClosing -Microsoft Windows任务管理器正在关闭应用程序。

FormOwnerClosing-所有者表单正在关闭。

ApplicationExitCall-调用Application类的Exit方法。


8
如果只是他们打破了UserClosing的粒度,那么您可以专门针对Alt + F4 ...
blak3r 2010年

如果(e.CloseReason == CloseReason.UserClosing){e.Cancel = true; }
adnan2nd '18

结合起来CloseReasonDialogResult以获得最佳效果。
Thomas Weller

25

我相信这是正确的方法:

protected override void OnFormClosing(FormClosingEventArgs e)
{
  switch (e.CloseReason)
  {
    case CloseReason.UserClosing:
      e.Cancel = true;
      break;
  }

  base.OnFormClosing(e);
}

更好的替换回破
Bahadır鸭肝

实际上,我相信正确的模式是将cancel标志设置为true,然后调用基类。重写On [Event]方法时,重要的是调用基类,以便也将事件通知给任何事件订阅者。是的,在这种情况下,很容易想到,既然您已经取消了该活动,那么其他人都不需要知道它,但是我认为做出这一假设是不正确的。
antyawn 2011年

我不确定原因,但是如果我调用基类,则在再次按下Alt + F4之后我的应用程序将崩溃。起初我以为是因为普通的F4在我的应用程序中还有其他含义,但漫长的调试会话却显示了其他含义。无论如何,这可能仍然是我这方面的一个具体案例。感谢您的出色回答。
Bahadır鸭肝

调用基类也会导致我的应用在后续的Alt + F4上崩溃。我怀疑基类没有检查e.Cancel并尝试破坏该表单。
Natan Yellin

您需要调查应用程序崩溃的原因-可能您在其他地方做错了。文档说:“ FormClosing事件是在关闭窗体时发生的。关闭窗体时,将释放该窗体,释放与该窗体关联的所有资源。如果取消此事件,则窗体保持打开状态。要取消关闭窗体窗体,将传递给事件处理程序的FormClosingEventArgs的Cancel属性设置为true。” tinyurl.com/3tb7y9q
antsawn

16

请注意,对于应用程序来说,完全阻止其自身关闭是一种不好的形式。您应该检查Closing事件的事件参数,以确定关闭应用程序的方式和原因。如果是由于Windows关闭导致的,则不应阻止关闭的发生。


13

您可以处理该FormClosing事件并将其设置FormClosingEventArgs.Canceltrue


12

我正在使用窗体作为弹出对话框来显示进度条,但我不希望用户能够将其关闭。

如果确定用户关闭了您的应用程序(并且知识渊博)足以按alt + f4,则他们很可能也足够知识渊博,可以运行任务管理器并杀死您的应用程序。

至少使用alt + f4,您的应用程序可以正常关闭,而不仅仅是让人们杀死它。从经验来看,人们杀死您的应用程序意味着损坏的配置文件,损坏的数据库,无法恢复的未完成任务以及许多其他痛苦的事情。

至少要以“您确定”来提示他们,而不是全力以赴阻止它。


8

这是禁用Alt+的技巧F4

private void test_FormClosing(object sender, FormClosingEventArgs e)
{
    if (this.ModifierKeys == Keys.Alt || this.ModifierKeys == Keys.F4) 
    { 
        e.Cancel = true; 
    }    
}

我可以确认这确实有效。但是,如果使用System.Windows.Forms,则需要检查staticControl.ModifierKeys属性,而不是该this.ModifierKeys属性(如上面的代码段所示)。
Special Sauce

这种方法更好,因为这样可以允许您使用具有CloseReason.UserClosing原因的Close()方法关闭应用程序。我对这种方法的担心是,当前按下的键信息是否总是准确的?
亚当LS

4

订阅FormClosing事件

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    e.Cancel = e.CloseReason == CloseReason.UserClosing;
}

方法主体中只有一行。


3

这可以做到:

bool myButtonWasClicked = false;
private void Exit_Click(object sender, EventArgs e)
{
  myButtonWasClicked = true;
  Application.Exit();
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
  if (myButtonWasClicked)
  {
    e.Cancel = false;
  }
  else
  {
    e.Cancel = true;
  }


}

2

即使您以编程方式关闭窗口,也会调用FormClosing吗?如果是这样,您可能希望添加一些代码以允许在完成表单后关闭该表单(而不是总是取消该操作)


您的问题的答案是“是”。请不要发布其他问题作为答案。已经有一个非常好的,高度投票和接受的答案。如果您不介意,请删除您的吗?它并没有真正增加价值。我已对您的答案中的3个进行了投票,以弥补删除的损失。
Thomas Weller

-3

通过在窗体的构造函数中使用以下命令,在窗体上隐藏关闭按钮:

this.ControlBox = false;
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.