How to Disable Alt + F4 closing form?
在 c# win 表单中禁用 Alt F4 以防止用户关闭表单的最佳方法是什么?
我正在使用表单作为弹出对话框来显示进度条,我不希望用户能够关闭它。
- 在 FormClosing 事件处理程序中,您是否可以不询问键盘缓冲区(您甚至可以访问此缓冲区吗?)以判断是否按下了 [Alt] [F4],如果为真则取消,如果不是则继续?
这样就可以了:
1
2 3 4 |
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{ e.Cancel = true; } |
编辑:针对 pix0rs 的关注 – 是的,您是正确的,您将无法以编程方式关闭应用程序。但是,您可以在关闭表单之前简单地删除 form_closure 事件的事件处理程序:
1
2 |
this.FormClosing -= new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing);
this.Close(); |
- 我怀疑大多数人都在有问题的表单(Form1)上实现此方法。在这种情况下,建议您不要附加委托,而是覆盖 OnFormClosing 方法。 “OnFormClosing 方法还允许派生类在不附加委托的情况下处理事件。这是在派生类中处理事件的首选技术。” tinyurl.com/3dzzljq
- 我会这样制作事件处理程序:e.Cancel = (e.Reason == CloseReason.UserClosing);。这样您就可以保证您不会仅在 USER 尝试关闭表单时关闭。
- 这种方法有一个大问题:如果您想关闭/重新启动您的 PC,它也会取消该请求,(至少在 Windows XP 上)
- 太精彩了!当您想关闭表单时,我特别喜欢删除事件。太简单了!!!
- @Will:我已经编辑了答案。现在有一个解决方案可以在不删除事件处理程序的情况下工作。
如果您查看 FormClosingEventArgs e.CloseReason 的值,它会告诉您为什么要关闭表单。然后您可以决定要做什么,可能的值是:
成员名称 – 描述
无 – 未定义或无法确定关闭的原因。
WindowsShutDown – 操作系统在关闭前关闭所有应用程序。
MdiFormClosing – 此多文档界面 (MDI) 表单的父表单正在关闭。
UserClosing – 用户正在通过用户界面 (UI) 关闭表单,例如通过单击表单窗口上的关闭按钮、从窗口的控制菜单中选择关闭或按 ALT F4。
TaskManagerClosing – Microsoft Windows 任务管理器正在关闭应用程序。
FormOwnerClosing – 所有者表单正在关闭。
ApplicationExitCall – 调用了 Application 类的 Exit 方法。
- 如果他们将 UserClosing 爆发得更细,这样您就可以专门针对 Alt F4 ……
- if (e.CloseReason == CloseReason.UserClosing) { e.Cancel = true; }
- 结合 CloseReason 和 DialogResult 以获得最佳效果。
我相信这是正确的做法:
1
2 3 4 5 6 7 8 9 10 11 |
protected override void OnFormClosing(FormClosingEventArgs e)
{ switch (e.CloseReason) { case CloseReason.UserClosing: e.Cancel = true; break; } base.OnFormClosing(e); |
- 更好地用返回代替rest
- 实际上,我相信正确的模式是将取消标志设置为 true,然后调用基类。当重写 On[Event] 方法时,调用基类很重要,这样任何事件订阅者也会收到该事件的通知。是的,在这种情况下,很容易认为既然您已经取消了活动,那么其他人就不需要知道它了,但我不认为做出这种假设是正确的。
- 我不确定原因,但如果我调用基类,我的应用程序会在随后的 Alt F4 再次按下后崩溃。起初我以为是因为普通的 F4 在我的应用程序中还有其他含义,但长时间的调试会话显示并非如此。无论如何,这可能仍然是我这边的一个具体案例。感谢这个伟大的答案。
- 调用基类也会导致我的应用在后续的 Alt F4 上崩溃。我怀疑基类没有检查 e.Cancel 并试图破坏表单。
- 您需要查看您的应用程序崩溃的原因——您很可能在其他地方做错了什么。文档说”FormClosing 事件在表单关闭时发生。当表单关闭时,它被释放,释放与表单关联的所有资源。如果取消此事件,表单保持打开状态。取消关闭一个表单,将传递给您的事件处理程序的 FormClosingEventArgs 的 Cancel 属性设置为 true。” tinyurl.com/3tb7y9q
- 您不应该在表单关闭中调用 base.OnFormClosing(e) 。它会导致堆栈溢出异常,您的应用程序将崩溃。
请注意,应用程序完全阻止自己关闭被认为是一种不好的形式。您应该检查 Closing 事件的事件参数以确定您的应用程序被要求关闭的方式和原因。如果是因为 Windows 关闭,则不应阻止关闭发生。
您可以处理 FormClosing 事件并将 FormClosingEventArgs.Cancel 设置为 true。
I am using a form as a popup dialog to display a progress bar and I do not want the user to be able to close it.
如果用户确定关闭您的应用程序(并且知识渊博)足以按下 alt f4,那么他们很可能也知识渊博,可以运行任务管理器并终止您的应用程序。
至少使用 alt f4,您的应用程序可以优雅地关闭,而不仅仅是让人们杀死它。根据经验,人们杀死您的应用程序意味着损坏的配置文件、损坏的数据库、无法恢复的半完成任务以及许多其他痛苦的事情。
至少用”你确定吗”提示他们,而不是直接阻止它。
这是禁用 Alt F4 的 hack。
1
2 3 4 5 6 7 |
private void test_FormClosing(object sender, FormClosingEventArgs e)
{ if (this.ModifierKeys == Keys.Alt || this.ModifierKeys == Keys.F4) { e.Cancel = true; } } |
- 我可以确认这确实有效。但是,如果使用 System.Windows.Forms,您将需要检查静态 Control.ModifierKeys 属性,而不是 this.ModifierKeys 属性(如上面的片段所示)。
- 这种方法更好,因为这样您可以允许使用 Close() 方法关闭应用程序,该方法共享 CloseReason.UserClosing 原因。我对这种方法的担忧是当前按下的键信息是否总是准确的?
订阅表单关闭事件
1
2 3 4 |
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{ e.Cancel = e.CloseReason == CloseReason.UserClosing; } |
方法体中只有一行。
这样就可以了:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
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; } } |
即使您以编程方式关闭窗口,也会调用 FormClosing 吗?如果是这样,您可能需要添加一些代码以允许在完成表单时关闭它(而不是总是取消操作)
- 您的问题的答案是”是”。请不要发布其他问题作为答案。已经有一个非常好的、高度投票和接受的答案。如果你不介意,请你删除你的吗?它并没有真正增加价值。我已对您的 3 个答案投了赞成票以弥补删除。
通过在表单的构造函数中使用以下内容来隐藏表单上的关闭按钮:
1
|
this.ControlBox = false;
|
来源:https://www.codenong.com/14943/