2010-03-19 6 views
8

Ich habe ein Kontrollkästchen und ich habe das CheckedChanged-Ereignis abonniert. Der Handler führt dort einige Operationen aus. Ich kontrolliere und deaktiviere das Kontrollkästchen programmgesteuert (zB: chkbx_Name.Checked = true) und das CheckedChanged-Ereignis wird ausgelöst.Problem in CheckedChanged-Ereignis

Ich möchte dieses Ereignis nur ausgelöst werden, wenn ich es manuell aktivieren oder deaktivieren. Gibt es eine Möglichkeit, das Auslösen dieses Ereignisses zu vermeiden, wenn ich es programmgesteuert ein-/auschecke?

Antwort

13

die Veranstaltung abmelden, bevor Sie eingestellt:

check1.CheckChanged -= check1_CheckChanged; 

dann können Sie programmatisch den Wert ohne die Checkbox gesetzt seine CheckChanged Ereignis Brennen:

check1.Checked = true; 

dann erneut abonnieren:

check1.CheckChanged += check1_CheckChanged; 

[EDIT: 29. März 2012]

Das Problem mit Tanvi Ansatz ist, dass Sie benötigen alle Quelle manuelle Überprüfung zu fangen oder deaktivieren. Nicht, dass es zu viele gibt (es ist nur durch Mausklick und vom Benutzer durch Drücken der Leertaste), aber Sie müssen in Erwägung ziehen, ein refaktoriertes Ereignis von MouseClick und KeyUp (Erkennung der Leertaste)

Es ist besser für eine CheckBox (keine Kontrolle für Das ist wichtig, um von der Quelle der Benutzereingabe (Tastatur, Maus, usw.) unabhängig zu sein, deshalb werde ich die programmatische Einstellung von CheckBox nur wirklich programmatisch machen. Zum Beispiel können Sie die programmatische Einstellung der Eigenschaft auf eine Erweiterungsmethode wickeln:

static class Helper 
{ 
    public static void SetCheckProgrammatically(
     this CheckBox c, 
     EventHandler subscribedEvent, bool b) 
    {    
     c.CheckedChanged -= subscribedEvent; // unsubscribe 
     c.Checked = b; 
     c.CheckedChanged += subscribedEvent; // subscribe 
    } 
} 

Mit diesem Ansatz kann Ihr Code reagiert ordentlich sowohl Maus der Benutzereingabe und Tastatureingabe über ein Ereignis nur, das heißt über CheckChanged. Keine Doppelung von Code, keine Notwendigkeit, mehrere Ereignisse zu abonnieren (zB Tastatur, Aktivieren/Deaktivieren der CheckBox durch Drücken der Leertaste)

+0

Ich mag diese Lösung, aber wenn es mehrere Programmierer in einem bestimmten Projekt gibt, dann müsste sich nicht jeder jedes Mal abmelden, wenn er diese Eigenschaft ändert? – Coops

+0

wrap es mit Erweiterungseigenschaften, er .. Extension-Methoden. z.B. check1.SetCheckedRaw (booleanHere) –

5

Nein. Diese Eigenschaftsänderungsereignisse werden ausgelöst, wenn sich der Eigenschaftswert ändert, unabhängig davon, ob dies von Ihrem Code, vom eigenen Code oder von der Datenbindung des Steuerelements ausgeführt wurde. Normalerweise ist es derselbe Codepfad.

Sie können jedoch, wenn Ihr Ereignishandler in derselben Klasse wie der Code liegt, der den Eigenschaftswert ändert, ein privates boolesches Feld in die Klasse einfügen, das Sie als Indikator für die aktuelle Eigenschaft verwenden Änderung wird durch Ihren Code oder durch den Benutzer ausgelöst. Nach Ihrer Änderung setzen Sie es einfach zurück. Der Event-Handler würde dann auf dem Feld sehen und entscheiden, ob es irgendetwas tun soll oder nicht:

class Foo : Form { 
    private bool checkedProgrammatically = false; 

    void someMethod() { 
     // ... 
     checkedProgrammatically = true; 
     checkBox1.Checked = true; 
     checkedProgrammatically = false; 
     // ... 
    } 

    private void checkBox1_CheckChanged(object sender, EventArgs e) { 
     if (checkedProgrammatically) return; 
     // ... 
    } 
} 
0

Sie boolean Variablenwert einstellen programiticaly vor dem Wechsel, und prüfen Sie als zurückgesetzt diese Variable in CheckedChanged Ereignisse

1

Es tut mir leid, ich kann Michael Bunes Antwort nicht kommentieren, weil ich neu hier bin (kein Ruf), aber für was es wert ist, bevorzuge ich seine Lösung für Johannes Rössel aus mehreren Gründen.

1) die checkedProgrammatically Variable ist ein bisschen zu nahe an global für mich. Es gibt nichts, was eine andere Methode daran hindern könnte, sie versehentlich auf "true" zu setzen, sodass alle Ihre Ereignisse gestoppt werden.

2) Sie könnten mit einer Menge von Variablen enden, abhängig von der Anzahl der Ereignisse, mit denen Sie zu tun haben. Es wäre einfach, das falsche zu ändern, und die Ergebnisse können schwierig zu debuggen sein.

3) Es ist offensichtlicher, was Sie tun, wenn Sie sich abmelden und dann erneut abonnieren. Die ganze Logik ist genau da, und Sie müssen Ihre Event-Handler nicht ändern, um abhängig von bestimmten Bedingungen vorzeitig zu beenden.

Ich habe beide Methoden ausgiebig verwendet und ich finde Michaels auf lange Sicht viel einfacher.

1

Sie können das MouseClick-Ereignis verwenden und dabei auf den aktivierten Status des Kontrollkästchens prüfen. So wird es nicht programmgesteuert ausgelöst, es wird nur aufgerufen, wenn der Benutzer die Checkbox manuell ein- oder auscheckt.

+1

Was passiert, wenn der Benutzer die CheckBox über die Leertaste an/auscheckt? nicht von der Maus? Siehe meine vorgeschlagene Lösung –