2011-11-11 5 views
26

Come si impedisce l'attivazione dell'evento CheckedChanged quando si controlla un controllo a livello di programmazione?Come prevenire l'attivazione dell'evento CheckedChanged quando si controlla un controllo a livello di programmazione?

Solitamente lo faccio nel seguente modo.

private bool isFrozen = false; 

private void btn1_CheckedChanged(object sender, EventArgs e) 
{ 
    if (isFrozen) 
     return; 

    isFrozen = true; 
    btn2.Checked = false; 
    isFrozen = false; 

    // Do some stuff 
} 

private void btn2_CheckedChanged(object sender, EventArgs e) 
{ 
    if (isFrozen) 
     return; 

    isFrozen = true; 
    btn1.Checked = false; 
    isFrozen = false; 

    // Do another stuff 
} 

Esiste una soluzione migliore o più comune?

+1

Questo è il modo corretto. Tecnicamente dovresti impostare isFrozen su false in un blocco finally. –

risposta

40

Penso che la tua strada sia soddisfacente.

L'altro modo per farlo è rimuovere EventHandler prima del controllo, quindi aggiungerlo di nuovo dopo il controllo. In questo modo si elimina la necessità della variabile isFrozen.

private void btn1_CheckedChanged(object sender, EventArgs e) 
{ 
    btn2.CheckedChanged -= btn2_CheckedChanged; 
    btn2.Checked = false; 
    btn2.CheckedChanged += btn2_CheckedChanged; 

    // Do some staff 
} 

private void btn2_CheckedChanged(object sender, EventArgs e) 
{ 
    btn1.CheckedChanged -= btn1_CheckedChanged; 
    btn1.Checked = false; 
    btn1.CheckedChanged += btn1_CheckedChanged; 

    // Do another staff 
} 
+0

Buona idea. Non ho mai pensato di rimuovere gli eventi. – Zenya

+0

bella soluzione semplice Lars – WraithNath

+1

Questo dovrebbe essere contrassegnato come la risposta corretta. Anche se non c'è una differenza evidente nel modo in cui funziona rispetto all'approccio dell'OP, questo esprime l'intento è un modo molto chiaro, quindi la prossima persona che lavora su questo codice può capire chiaramente cosa viene fatto e perché, anche senza commenti per spiegarlo. – Jim

5

In VB:

RemoveHandler btn2.CheckedChanged, AddressOf btn2_CheckedChanged 
btn2.Checked = false 
AddHandler btn2.CheckedChanged, AddressOf btn2_CheckedChanged 
+3

La risposta riguardava C# non VB. –

+4

Ma è utile per alcuni di noi che hanno pensato a come farlo in C# (la nostra prima lingua), ma hanno dovuto scrivere il codice in VB.net (richiesta del cliente). –

+0

Anche se ho apprezzato molto questa risposta, penso che dovrebbe essere aggiunta come commento alla risposta accettata. – Eric

4

mi sono imbattuto in questo post dopo che vogliono implementare qualcosa di simile a questo per un po '. Utilizzo regolarmente Measurement Studio da National Instruments e i relativi controlli WinForm che hanno l'evento StateChanging o StateChanged che passano un parametro di tipo ActionEventArgs, che ha una proprietà Action che può assumere tre valori: ByKeyboard, ByMouse e Programatic. Questo è molto utile per determinare cosa ha causato la modifica dello stato del controllo. Volevo replicarlo in una casella di controllo standard di WinForms.

Ecco il mio codice:

public enum ControlSource 
{ 
    Programatic, 
    ByKeyboard, 
    ByMouse 
} 

public class AwareCheckBox : Checkbox 
{ 
    public AwareCheckBox() 
      : base() 
    { 
     this.MouseDown += AwareCheckbox_MouseDown; 
     this.KeyDown += AwareCheckbox_KeyDown; 
    } 

    private ControlSource controlSource = ControlSource.Programatic; 

    void AwareCheckbox_KeyDown(object sender, KeyEventArgs e) 
    { 
     controlSource = ControlSource.ByKeyboard; 
    } 

    void AwareCheckbox_MouseDown(object sender, MouseEventArgs e) 
    { 
     controlSource = ControlSource.ByMouse; 
    } 

    public new event AwareControlEventHandler CheckedChanged; 
    protected override void OnCheckedChanged(EventArgs e) 
    { 
     var handler = CheckedChanged; 
     if (handler != null) 
      handler(this, new AwareControlEventArgs(controlSource)); 

     controlSource = ControlSource.Programatic; 
    } 
} 

public delegate void AwareControlEventHandler(object source, AwareControlEventArgs e); 

public class AwareControlEventArgs : EventArgs 
{ 
    public ControlSource Source { get; private set; } 

    public AwareControlEventArgs(ControlSource s) 
    { 
     Source = s; 
    } 
} 

Sono sicuro che ci sono miglioramenti da fare, ma il mio test rudimentale ha dimostrato che funziona. Ho postato qui semplicemente nel caso in cui altri si imbattessero in questo problema e volessero un modo più chiaro di distinguere dove è stata avviata la modifica. Qualsiasi commento benvenuto.

Problemi correlati