Come EventArgs Annulla lavoro nel FormClosing evento?
-
11-09-2019 - |
Domanda
Come funziona la manifestazione e.Cancel in caso FormClosing su una WinForm? So che si imposta su True
di annullare la chiusura, ma a che punto del processo di modulo questo? C'è un'azione secondaria presa dalla proprietà?
Come potrei attuare un'azione simile in un controllo personalizzato? (C # o VB)
Nota: Ho cercato per circa 30 minuti e ora non sono riuscito a trovare alcuna risposta in Google o il SO di ricerca, quindi se si tratta di un duplicato, il mio male
.Soluzione
Credo che il manifesto originale potrebbe chiedere che cosa succede quando alcuni abbonati impostati Cancel = false
e alcuni abbonati impostare Cancel = true
. Se questo è il caso, allora la domanda "quando fa il processo di modulo di questo" assume più importanza.
In un primo momento mi sono chiesto se il palleggiatore è stato implementato per OR o AND ogni valore. Utilizzando Reflector per ispezionare il setter per CancelEventArgs.Cancel
mostra pone semplicemente un campo privato:
public bool Cancel
{
get{ return this.cancel; }
set{ this.cancel = value; }
}
Così ho pensato sbirciare in 'Form.OnClosing (CancelEventArgs args)' avrebbe mostrato quando il valore viene controllato, come le risposte precedenti, ma che non è quello che mostra riflettore:
[EditorBrowsable(EditorBrowsableState.Advanced)]
protected virtual void OnClosing(CancelEventArgs e)
{
CancelEventHandler handler = (CancelEventHandler) base.Events[EVENT_CLOSING];
if (handler != null)
{
handler(this, e);
}
}
Così ho attivato il debug source e trovato ottenere il delegato EVENT_CLOSING
dalla collezione Events
scende in profondità nella API di finestre in modo tale che handler
nella prima riga del OnClosing
è null
quando la forma imposta Cancel = true
, cioè il codice gestito non test veramente se CancelEventArgs.Cancel == true
. Se si desidera che le brutte budella di ciò che accade all'interno del EventHandlerList, si ottiene questo:
get {
ListEntry e = null;
if (parent == null || parent.CanRaiseEventsInternal)
{
e = Find(key);
}
if (e != null) {
return e.handler;
}
else {
return null;
}
}
Durante il debug, parent.CanRaiseEventsInternal
è falso se la chiusura è stata annullata.
Quindi ... l'effettiva attuazione di annullare la chiusura di una forma è più complicata di quanto le risposte precedenti, ma i loro suggerimenti su come annullare i propri eventi mostrano correttamente come farlo in codice gestito. Chiamare il CancelEventHandler e quindi verificare il valore di CancelEventArgs.Cancel
dopo che tutti gli abbonati hanno avuto la possibilità di impostare il valore true
. Questo ancora non risponde cosa succede se alcuni abbonati impostati Cancel = false
e un insieme Cancel = true
. Qualcuno sa? Sarebbe necessario qualcosa di simile a quanto segue?
public bool Cancel
{
get{ return this.cancel; }
set{ this.cancel = this.cancel || value; }
}
Altri suggerimenti
A seguito dell'evento generano tracciati standard utilizzato in Windows Form:
public event CancelEventHandler MyEvent;
protected void OnMyEvent(CancelEventArgs e) {
CancelEventHandler handler = MyEvent;
if (handler != null) {
handler(this, e);
}
}
private void button1_Click(object sender, EventArgs e) {
CancelEventArgs args = new CancelEventArgs();
OnMyEvent(args);
if (!args.Cancel) {
// Client code didn't cancel, do your stuff
//...
}
}
function OnMyCancelableEvent()
{
var handler = CancelableEvent;
var args = new CancelEventArgs()
if(handler != null)
{
handler(this, args)
if(args.Canceled)
// do my cancel logic
else
// do stuff
}
}