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.


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

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.


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

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.


13

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


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.


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

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.


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


}

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).


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;
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.