Wie deaktiviere ich das Alt + F4-Abschlussformular?

78

Was ist der beste Weg, um Alt+ F4in ac # win-Formular zu deaktivieren, um zu verhindern, dass der Benutzer das Formular schließt?

Ich verwende ein Formular als Popup-Dialogfeld, um einen Fortschrittsbalken anzuzeigen, und möchte nicht, dass der Benutzer ihn schließen kann.

Ryan Sampson
quelle
Könnten Sie im FormClosing-Ereignishandler den Tastaturpuffer nicht abfragen (haben Sie überhaupt Zugriff darauf?), Um zu sehen, ob [Alt] + [F4] gedrückt wurde, abbrechen, wenn true, fortfahren, wenn nicht?
TK.

Antworten:

106

Das macht den Job:

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

Bearbeiten: Als Reaktion auf die Bedenken von pix0rs - ja, Sie haben Recht, dass Sie die App nicht programmgesteuert schließen können. Sie können den Ereignishandler für das Ereignis form_closing jedoch einfach entfernen, bevor Sie das Formular schließen:

this.FormClosing -= new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing);
this.Close();
Martin
quelle
4
Ich vermute, dass die meisten Leute diese Methode auf dem fraglichen Formular (Form1) implementieren. In diesem Fall wird empfohlen, keinen Delegaten anzuhängen, sondern die OnFormClosing-Methode zu überschreiben. "Mit der OnFormClosing-Methode können abgeleitete Klassen das Ereignis auch behandeln, ohne einen Delegaten anzuhängen. Dies ist die bevorzugte Technik für die Behandlung des Ereignisses in einer abgeleiteten Klasse." tinyurl.com/3dzzljq
antsyawn
9
Ich hätte den Event-Handler als solchen gemacht : e.Cancel = (e.Reason == CloseReason.UserClosing);. Auf diese Weise stellen Sie sicher, dass Sie nicht nur schließen, wenn der BENUTZER versucht, das Formular zu schließen.
Paulo Santos
Dieser Ansatz hat ein großes Problem: wenn Sie shutdown / PC neu starten wollen , wird es diesen Antrag storniert auch (zumindest unter Windows XP)
conceptacid
Das ist hervorragend! Ich liebe es besonders, das Ereignis zu entfernen, wenn Sie das Formular schließen möchten. Es ist so einfach!!!
Wird
@ Will: Ich habe die Antwort bearbeitet. Es gibt jetzt eine Lösung, die funktioniert, ohne den Ereignishandler zu entfernen.
Thomas Weller
59

Wenn Sie sich den Wert von ansehen FormClosingEventArgs e.CloseReason, erfahren Sie, warum das Formular geschlossen wird. Sie können dann entscheiden, was zu tun ist. Die möglichen Werte sind:

Mitgliedsname - Beschreibung


Keine - Die Ursache der Schließung wurde nicht definiert oder konnte nicht ermittelt werden.

WindowsShutDown - Das Betriebssystem schließt alle Anwendungen vor dem Herunterfahren.

MdiFormClosing - Das übergeordnete Formular dieses MDI-Formulars (Multiple Document Interface) wird geschlossen.

UserClosing - Der Benutzer schließt das Formular über die Benutzeroberfläche, indem er beispielsweise im Formularfenster auf die Schaltfläche Schließen klickt, im Steuerungsmenü des Fensters die Option Schließen auswählt oder ALT+ drückt F4.

TaskManagerClosing - Der Microsoft Windows Task-Manager schließt die Anwendung.

FormOwnerClosing - Das Eigentümerformular wird geschlossen.

ApplicationExitCall - Die Exit-Methode der Application-Klasse wurde aufgerufen.

Matt Warren
quelle
8
Wenn nur UserClosing ausgebrochen wäre, um detaillierter zu sein, könnten Sie Alt + F4 gezielt
anvisieren
if (e.CloseReason == CloseReason.UserClosing) {e.Cancel = true; }
adnan2nd
Kombinieren CloseReasonund DialogResultfür beste Ergebnisse.
Thomas Weller
25

Ich glaube, das ist der richtige Weg:

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

  base.OnFormClosing(e);
}
antsyawn
quelle
Ersetzen Sie die Pause besser durch Rückkehr
Bahadır Yağan
Eigentlich glaube ich, dass das richtige Muster darin besteht, das Abbruchflag auf true zu setzen und dann die Basisklasse aufzurufen. Beim Überschreiben von On [Event] -Methoden ist es wichtig, die Basisklasse aufzurufen, damit alle Ereignisabonnenten ebenfalls über das Ereignis informiert werden. Ja, in diesem Fall ist es leicht zu glauben, dass niemand anderes davon wissen muss, da Sie die Veranstaltung abgesagt haben, aber ich glaube nicht, dass es richtig ist, diese Annahme zu treffen.
Antsyawn
Ich bin mir über den Grund nicht sicher, aber wenn ich die Basisklasse aufrufe, stürzt meine Anwendung nach einem weiteren nachfolgenden Alt + F4-Treffer ab. Zuerst dachte ich, es liege daran, dass einfaches F4 in meiner Anwendung eine andere Bedeutung hat, aber eine lange Debugging-Sitzung zeigte etwas anderes. Wie auch immer, es kann immer noch ein spezifischer Fall auf meiner Seite sein. Danke für diese tolle Antwort.
Bahadır Yağan
Das Aufrufen der Basisklasse führt auch dazu, dass meine App bei nachfolgenden Alt + F4s abstürzt. Ich vermute, dass die Basisklasse e.Cancel nicht überprüft und trotzdem versucht, das Formular zu zerstören.
Natan Yellin
Sie müssen untersuchen, warum Ihre Anwendung abstürzt - wahrscheinlich machen Sie anderswo etwas falsch. In den Dokumenten heißt es: "Das FormClosing-Ereignis tritt auf, wenn das Formular geschlossen wird. Wenn ein Formular geschlossen wird, wird es entsorgt, wodurch alle mit dem Formular verbundenen Ressourcen freigegeben werden. Wenn Sie dieses Ereignis abbrechen, bleibt das Formular geöffnet. Um das Schließen eines Formulars abzubrechen." Setzen Sie die Cancel-Eigenschaft der an Ihren Ereignishandler übergebenen FormClosingEventArgs auf true. " tinyurl.com/3tb7y9q
antsyawn
16

Beachten Sie, dass es für eine Anwendung als schlechte Form angesehen wird, das Schließen vollständig zu verhindern. Sie sollten die Ereignisargumente für das Closing-Ereignis überprüfen, um festzustellen, wie und warum Ihre Anwendung zum Schließen aufgefordert wurde. Wenn dies auf ein Herunterfahren von Windows zurückzuführen ist, sollten Sie das Schließen nicht verhindern.

Lasse V. Karlsen
quelle
13

Sie könnten den Griff FormClosingEreignis und Satz FormClosingEventArgs.Cancelzu true.

Timbo
quelle
12

Ich verwende ein Formular als Popup-Dialogfeld, um einen Fortschrittsbalken anzuzeigen, und möchte nicht, dass der Benutzer ihn schließen kann.

Wenn der Benutzer entschlossen ist, Ihre App zu schließen (und über ausreichende Kenntnisse verfügt), um Alt + F4 zu drücken, verfügt er höchstwahrscheinlich auch über ausreichende Kenntnisse, um den Task-Manager auszuführen und stattdessen Ihre Anwendung zu beenden.

Zumindest mit alt + f4 kann Ihre App ordnungsgemäß heruntergefahren werden, anstatt nur Leute dazu zu bringen, sie zu töten. Aus Erfahrung bedeutet das Töten Ihrer App, dass Benutzer Ihre App beschädigen, beschädigte Datenbanken, halbfertige Aufgaben, die Sie nicht fortsetzen können, und viele andere schmerzhafte Dinge.

Fordern Sie sie zumindest mit "Sind Sie sicher" auf, anstatt dies zu verhindern.

Orion Edwards
quelle
7

Dies ist ein Hack zum Deaktivieren von Alt+ F4.

private void test_FormClosing(object sender, FormClosingEventArgs e)
{
    if (this.ModifierKeys == Keys.Alt || this.ModifierKeys == Keys.F4) 
    { 
        e.Cancel = true; 
    }    
}
Brahim Bourass
quelle
Ich kann bestätigen, dass dies funktioniert. Wenn System.Windows.FormsSie jedoch verwenden, müssen Sie die statische Control.ModifierKeysEigenschaft anstelle der this.ModifierKeysEigenschaft überprüfen (wie im obigen Snippet gezeigt).
Spezielle Soße
4

Abonnieren Sie das FormClosing-Ereignis

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

Nur eine Zeile im Methodenkörper.

linquize
quelle
3

Das macht den Job:

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


}
Condorkunka
quelle
2

Würde FormClosing auch dann aufgerufen, wenn Sie das Fenster programmgesteuert schließen? In diesem Fall möchten Sie wahrscheinlich Code hinzufügen, damit das Formular geschlossen werden kann, wenn Sie damit fertig sind (anstatt den Vorgang immer abzubrechen).

pix0r
quelle
Die Antwort auf Ihre Frage lautet "Ja". Bitte stellen Sie keine zusätzlichen Fragen als Antwort. Es gibt bereits eine wirklich gute, hoch gewählte und akzeptierte Antwort. Wenn es Ihnen nichts ausmacht, würden Sie bitte Ihre löschen? Es ist kein wirklicher Mehrwert. Ich habe 3 Ihrer Antworten positiv bewertet, um die Löschung zu kompensieren.
Thomas Weller
-3

Blenden Sie die Schaltfläche zum Schließen des Formulars aus, indem Sie im Konstruktor des Formulars Folgendes verwenden:

this.ControlBox = false;
Bharath Theorare
quelle