Überschreiben Sie die Standardschaltfläche (X) in einem Windows Form


75

Wie ändere ich, was passiert, wenn ein Benutzer in einer Windows Forms-Anwendung (in C #) auf die Schaltfläche zum Schließen (rotes X) klickt?

Antworten:


135

Sie können OnFormClosing dazu überschreiben . Achten Sie nur darauf, dass Sie nichts Unerwartetes tun, da das Klicken auf das 'X' zum Schließen ein gut verstandenes Verhalten ist.

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

3
Ich vermute, er möchte das Tablett minimieren, aber Sie erhalten die +1 von mir, wenn Sie sagen, seien Sie vorsichtig.
Sam Harwell

4
@ Jon B - Sie sollten den nahen Grund überprüfen. Wenn Windows heruntergefahren wird, möchten Sie keine Meldungsfelder anzeigen.
Philip Wallace

1
Ich habe es zu einer switch-Anweisung gemacht, damit ich nicht nach rechts scrollen muss, um die rechte Seite des==
Sam Harwell

2
@Philip: Nun, das hängt davon ab. Ein Feld "Möchten Sie speichern" sollte jedes Mal angezeigt werden, wenn es relevant ist (es gibt Änderungen), und das Abbrechen sollte das Herunterfahren abbrechen. Das passiert zum Beispiel mit VS. Ein nerviges "Willst du schließen" sollte angezeigt werden ... im Idealfall niemals, aber wenn du diesen Weg gehst, solltest du dieses beim Herunterfahren umgehen.
R. Martinho Fernandes

@Phillip - wird das eigentlich empfohlen? Ich glaube, die meisten Anwendungen werden Sie fragen, ob Sie Änderungen an einer geänderten Datei speichern möchten, unabhängig vom nahen Grund.
Groo

20

Überschreiben Sie die OnFormClosing- Methode.

VORSICHT: Sie müssen den CloseReason überprüfen und das Verhalten nur ändern, wenn es sich um UserClosing handelt. Sie sollten hier nichts einfügen, was das Herunterfahren von Windows zum Stillstand bringen würde.

Änderungen beim Herunterfahren der Anwendung in Windows Vista

Dies ergibt sich aus den Anforderungen des Windows 7-Logo-Programms .


Bieten sie eine Ausnahme an, wenn Sie den Benutzer auffordern, vor dem Herunterfahren Arbeit zu speichern?
Christopher B. Adkins

18

Eine Sache, die diesen Antworten fehlt und nach der Neulinge wahrscheinlich suchen, ist, dass es zwar schön ist, eine Veranstaltung zu haben:

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

Es wird überhaupt nichts tun, wenn Sie die Veranstaltung nicht registrieren . Fügen Sie dies in den Klassenkonstruktor ein:

this.FormClosing += Form1_FormClosing;

10

Überschreiben Sie entweder OnFormClosing oder registrieren Sie sich für das Ereignis FormClosing .

Dies ist ein Beispiel für das Überschreiben der OnFormClosing-Funktion in der abgeleiteten Form:

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

Dies ist ein Beispiel für den Handler des Ereignisses, um das Schließen des Formulars zu verhindern, das sich in einer beliebigen Klasse befinden kann:

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

Überprüfen Sie die CloseReason-Eigenschaft in FormClosingEventArgs, um sicherzustellen, dass die entsprechende Aktion ausgeführt wird, um weitere Informationen zu erhalten. Möglicherweise möchten Sie die alternative Aktion nur ausführen, wenn der Benutzer versucht, das Formular zu schließen.


8

wie Jon B sagte, aber Sie möchten auch nach dem ApplicationExitCallund TaskManagerClosingCloseReason suchen:

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


3

Eine Situation, in der es sehr nützlich ist, das X-Button-Klickereignis verarbeiten zu können, ist die Verwendung eines Formulars, das ein MDI-Container ist. Der Grund ist, dass die abschließenden und geschlossenen Ereignisse zuerst mit Kindern und zuletzt mit den Eltern ausgelöst werden. In einem Szenario klickt ein Benutzer auf die x-Schaltfläche, um die Anwendung zu schließen, und der übergeordnete MDI-Benutzer fordert eine Bestätigung an, um fortzufahren. Falls er beschließt, den Antrag nicht zu schließen, sondern fortzufahren, was auch immer er tut, haben die Kinder das Abschlussereignis bereits verarbeitet und möglicherweise Informationen / Arbeit verloren. Eine Lösung besteht darin, die WM_CLOSE-Nachricht aus der Windows-Nachrichtenschleife in Ihrem Hauptanwendungsformular abzufangen (dh welches die Anwendung schließt, beendet) wie folgt:

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

1

Dies ist eine ziemlich häufig gestellte Frage. Eine gute Antwort ist hier:

VB.NET überlastet die Standardfunktionalität, wenn der Benutzer auf das X klickt (Programm schließen).


Wenn Sie Ihren Code nicht in das Form_Closing-Ereignis einfügen möchten, ist mir nur ein "Hack" bekannt, den ich ein- oder zweimal verwendet habe. Es sollte nicht notwendig sein, auf diesen Hack zurückzugreifen, aber hier ist es:


Verwenden Sie nicht die normale Schaltfläche zum Schließen. Erstellen Sie stattdessen Ihr Formular so, dass es keine ControlBox enthält. Sie können dies tun, indem Sie im Formular ControlBox = false festlegen. In diesem Fall wird weiterhin der normale Balken oben im Formular angezeigt, oder Sie können den FormBorderStyle des Formulars auf "Keine" setzen. Wenn Sie diesen zweiten Weg gehen, dort Es wird kein Balken über der Oberseite oder ein anderer sichtbarer Rand angezeigt. Sie müssen diese also entweder durch Zeichnen auf dem Formular oder durch künstlerische Verwendung von Bedienfeldsteuerelementen simulieren.

Dann können Sie eine Standardschaltfläche hinzufügen und sie wie eine Schaltfläche zum Schließen aussehen lassen und dort Ihren Bereinigungscode einfügen. Rufen Sie am Ende des Schaltflächenereignisses einfach this.Close()(C #) oder Me.Close()(VB) auf.


Warum sollte man sich beim Abschluss des Events nicht wohl fühlen? IMHO ist das Hinzufügen einer benutzerdefinierten (aber überzeugenden) Schaltfläche zum Schließen nicht so trivial (insbesondere, wenn Sie Übergangseffekte und Aero-Inhalte berücksichtigen, die Sie normalerweise ohne Schmerzen erhalten).
Groo

In der Antwort, auf die ich verlinkt habe, wollte die Person, die die Frage gestellt hat, aus irgendeinem Grund das Ereignis Form_Closing nicht verwenden. Ich bin mir nicht sicher, was sein Grund war, aber er wollte es nicht benutzen. Als ich den Hack benutzte, wollte ich nur einen Schließknopf mit einem anderen Aussehen.
David

Mit anderen Worten, die andere Antwort war sowohl mit (fair genug) verknüpft als auch kopiert, weshalb die Hälfte der Antwort irrelevant ist und der Rest etwas empfiehlt, das hier keine Rechtfertigung hat.
JWG

0

Die akzeptierte Antwort funktioniert ganz gut. Eine alternative Methode, die ich verwendet habe, besteht darin, eine FormClosing-Methode für das Hauptformular zu erstellen. Dies ist dem Override sehr ähnlich. Mein Beispiel ist eine Anwendung, die beim Klicken auf die Schaltfläche zum Schließen im Formular auf die Taskleiste minimiert wird.

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    {
        if (e.CloseReason == CloseReason.ApplicationExitCall)
        {
            return;
        }
        else
        {
            e.Cancel = true;
            WindowState = FormWindowState.Minimized;
        }            
    }

Dies ermöglicht ALT + F4 oder irgendetwas in der Anwendung, das Application.Exit () aufruft . Wenn Sie beim Klicken auf (X) wie gewohnt vorgehen, wird die Anwendung minimiert.


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