2010-04-21 9 views
67

In MSDN ho trovato CloseReason.UserClosing per sapere che l'utente aveva deciso di chiudere il modulo ma suppongo che sia lo stesso per entrambi facendo clic sul pulsante X o facendo clic sul pulsante Chiudi. Quindi, come posso distinguere tra questi due nel mio codice?Come sapere che l'utente ha cliccato su "X" o sul pulsante "Chiudi"?

Grazie a tutti.

+1

quale pulsante di chiusura intendi? –

+0

Cosa "pulsante Chiudi"? – SLaks

+0

per esempio chiudendo con "ALT + F4" – Bohn

risposta

66

Supponendo che si stiano chiedendo WinForms, è possibile utilizzare FormClosing() event. L'evento FormClosing() viene attivato ogni volta che un modulo deve essere chiuso.

Per rilevare se l'utente ha fatto clic su X o Chiudi, è possibile visualizzarlo tramite l'oggetto mittente. Prova a trasmettere il mittente come controllo Button e, ad esempio, a verificare forse il suo nome "CloseButton".

private void Form1_FormClosing(object sender, FormClosingEventArgs e) { 
    if (string.Equals((sender as Button).Name, @"CloseButton")) 
     // Do something proper to CloseButton. 
    else 
     // Then assume that X has been clicked and act accordingly. 
} 

In caso contrario, non ho mai mai avuto bisogno di distinguere se X o CloseButton stato cliccato, come ho voluto realizzare qualcosa di specifico sull'evento FormClosing, come chiudere tutte le MdiChildren prima di chiudere il MDIContainerForm, o l'evento controllando modifiche non salvate . In queste circostanze, non abbiamo bisogno, secondo me, di differenziare da entrambi i pulsanti.

Chiusura per ALT +F4 anche attivare l'evento FormClosing(), come si invia un messaggio al modulo che dice di chiudere. È possibile annullare l'evento impostando il

FormClosingEventArgs.Cancel = true. 

Nel nostro esempio, questo si tradurrebbe in essere

e.Cancel = true. 

notare la differenza tra il FormClosing() e le FormClosed() eventi.

FormClosing si verifica quando il modulo ha ricevuto il messaggio da chiudere e verifica se ha qualcosa da fare prima che venga chiuso.

FormClosed si verifica quando il modulo è effettivamente chiuso, quindi dopo che è chiuso.

Questo aiuto?

+0

Sì, grazie per l'idea "Cast", aveva usato questo tecnica con Delphi 7 ma ho dimenticato di fare lo stesso in C# – Bohn

+0

Questa infatti è una porta da Delphi a .NET. =) Sono felice di aver aiutato! –

+0

Ottengo "Riferimento oggetto non impostato su un'istanza di un oggetto" quando utilizzo questo codice. –

69

Il CloseReason enumerazione che hai trovato su MSDN è solo per lo scopo di verificare se l'utente ha chiuso l'applicazione, o è stato a causa di un arresto, o chiuso dal task manager, ecc ...

Puoi fare azioni diverse, a seconda della ragione, come:

void Form_FormClosing(object sender, FormClosingEventArgs e) 
{ 
    if(e.CloseReason == CloseReason.UserClosing) 
     // Prompt user to save his data 

    if(e.CloseReason == CloseReason.WindowsShutDown) 
     // Autosave and clear up ressources 
} 

Ma, come avete indovinato, non v'è alcuna differenza tra clic sul pulsante x, o rightclicking la barra delle applicazioni e facendo clic su 'stretta', o premendo AltF4, ecc. Tutto finisce in un motivo CloseReason.UserClosing.

+6

Utilizzo dello standard Chiudi(); sembra attivare CloseReason.UserClosing per me. Non so perché. –

+0

Ho trovato utile questo quando si tenta di bloccare la chiusura di un modulo figlio MDI mediante l'azione dell'utente sul modulo ma non quando il genitore viene chiuso. –

+1

Questo non risponde alla domanda, solo enumerare ulteriormente il problema. –

35

Il pulsante "X" si registra come DialogResult.Cancel in modo che un'altra opzione sia la valutazione dello .

Se nel modulo sono presenti più pulsanti, probabilmente stai già associando diversi DialogResult a ciascuno e questo ti fornirà i mezzi per distinguere tra ciascun pulsante.

(Esempio: btnSubmit.DialogResult = DialogResult.OK, btnClose.DialogResult = Dialogresult.Abort)

public Form1() 
    { 
     InitializeComponent(); 

     this.FormClosing += Form1_FormClosing; 
    } 

    /// <summary> 
    /// Override the Close Form event 
    /// Do something 
    /// </summary> 
    /// <param name="sender"></param> 
    /// <param name="e"></param> 
    private void Form1_FormClosing(Object sender, FormClosingEventArgs e) 
    { 
     //In case windows is trying to shut down, don't hold the process up 
     if (e.CloseReason == CloseReason.WindowsShutDown) return; 

     if (this.DialogResult == DialogResult.Cancel) 
     { 
      // Assume that X has been clicked and act accordingly. 
      // Confirm user wants to close 
      switch (MessageBox.Show(this, "Are you sure?", "Do you still want ... ?", MessageBoxButtons.YesNo, MessageBoxIcon.Question)) 
      { 
       //Stay on this form 
       case DialogResult.No: 
        e.Cancel = true; 
        break; 
       default: 
        break; 
      } 
     } 
    } 
+0

Nel mio caso questo è più utile della risposta accettata. Poiché la "X" viene assegnata a DialogResult.Cancel, l'assegnazione di qualche altro valore al pulsante di annullamento li distingue facilmente e gestisce le cose in modo appropriato. – mickeyf

+3

Questo non funziona nel mio caso. Quando si preme 'X', 'DialogResult' rimane' None'. Quale potrebbe essere il problema? – Bhaskar

+1

@Bhaskar, quando si crea un'istanza della finestra di dialogo, assicurarsi di impostare il DialogResult appropriato per ciascun pulsante nella finestra di dialogo. Ho fornito un esempio sopra ma non ho creato un blocco di codice per mostrare la dichiarazione Dialog. – AlexScript

1
if (this.DialogResult == DialogResult.Cancel) 
     { 

     } 
     else 
     { 
      switch (e.CloseReason) 
      { 
       case CloseReason.UserClosing: 
        e.Cancel = true; 
        break; 
      } 
     } 

se condizione eseguirà quando utente clicca il pulsante di chiusura sulla forma 'X' o. Il resto può essere utilizzato quando l'utente fa clic su Alt + f4 per altri scopi

6

Determina quando chiudere l'applicazione se un modulo è chiuso (se l'applicazione non è collegata a un modulo specifico).

private void MyForm_FormClosed(object sender, FormClosedEventArgs e) 
    { 
     if (Application.OpenForms.Count == 0) Application.Exit(); 
    } 
1

Si può provare ad aggiungere gestore di eventi dal progetto come questo: modulo Open in vista di disegno, aprire la finestra delle proprietà o premere F4, fare clic sul pulsante della barra degli strumenti eventi per visualizzare gli eventi in oggetto Form, trovare FormClosing evento nel gruppo Comportamento, e fai doppio clic. Riferimento: https://social.msdn.microsoft.com/Forums/vstudio/en-US/9bdee708-db4b-4e46-a99c-99726fa25cfb/how-do-i-add-formclosing-event?forum=csharpgeneral

Problemi correlati