Thomas Bandt

Über mich | Kontakt | Archiv

Event, Event, ein Lichtlein brennt.

Oder so ähnlich. Ich stand gestern ganz schön im Wald, Grund: das Event-Handling - bzw. der Unterschied zw. ASP.NET und "echten Forms" in diesem Gebiet.

Von ASP.NET bin ich es gewohnt, dass ein Event erst wirklich dann gefeuert wird, wenn der User entsprechend interagiert - klar, HTTP ist zustandslos, ASP.NET nach Auslieferung des HTML-Dokumentes tot - da geht es erst weiter bzw. wieder los, wenn ein Request an den Server geschickt wird.

Im konkreten Beispiel ging es bei mir um eine DropDownList (bzw. ComboBox), für die ein OnSelectedIndexChanged-Event definiert war. Bei ASP.NET muss der Benutzer tatsächlich etwas neues auswählen, damit die Event-Methode aufgerufen wird, nun ging ich erstmal davon aus, dass das bei Winforms auch so ist.

Ich setzte also meine ComboBox in die Form, klickte einmal doppelt drauf, platzierte eine Reihe "teuren" Code darin. Beim nächsten Start der Form wunderte ich mich schon, warum alles so lange dauert ...

Was war passiert?

Ganz einfach: ich hatte beim Initialisieren der Box selbstverständlich Werte eingefüllt. Und bei jedem neuen via Add() hinzugefügten Item wurde das Event gefeuert ... -> Klar - es änderte sich ja der Index! Und da wir uns hier nicht mehr im zustandslosen Raum befinden, sondern die Form "live" mitbekommt, was passiert, wurde nun das Event immer gleich gefeuert.

Die Lösung dafür: das Event wird erst nach dem Initialisieren von Hand registriert. Normalerweise erledigt das gleich Visual Studio beim Doppelklick auf die ComboBox, deshalb muss der Eintrag aus der Form.Designer.cs herausgenommen, und einfach nach die Initialisierung gesetzt werden:

this.comboBox1.SelectedIndexChanged += new
System.EventHandler(this.comboBox1_SelectedIndexChanged);

Kommentare

  1. Matthias Leonhardt schrieb am Mittwoch, 12. Juli 2006 09:20:00 Uhr:

    hiho Thomas,

    kann man vor dem Füllen nicht einfach BeginUpdate() und danach EndUpdate() aufrufen? Damit müßte doch das Zeichnen und die Events entkoppelt werden.

    Grüße, Matthias
  2. Thomas schrieb am Mittwoch, 12. Juli 2006 09:30:00 Uhr:

    Wenn das so wäre ... noch besser, keine Ahnung. Probiere ich bei Gelegenheit mal aus. Danke für den Tipp!
  3. Thomas schrieb am Mittwoch, 12. Juli 2006 10:47:00 Uhr:

    Habe es eben mal ausprobiert - vor allen Add und Select-Aktionen BeginUpdate() und nachher EndUpdate() gesetzt - ohne Erfolg. Die Event-Methoden wurden trotzdem aufgerufen.
  4. Thommy schrieb am Donnerstag, 13. Juli 2006 09:06:00 Uhr:

    BeginUpdate: "This method prevents the control from _painting_ until the EndUpdate method is called."

    Der korrekte Weg wäre, den Eventhandler erst nach dem Befüllen der Combobox per Code hinzuzufügen, dann klappt's auch mit dem Nachbarn.
  5. Thomas schrieb am Donnerstag, 13. Juli 2006 11:27:00 Uhr:

    Mach ich doch :-)
  6. Thommy schrieb am Donnerstag, 13. Juli 2006 12:38:00 Uhr:

    Sag' ich doch :-)
  7. Floyd schrieb am Mittwoch, 26. Juli 2006 17:15:00 Uhr:

    Hallo Thomas, dein Problem läßt sich auch anders lösen.

    Dim x As New Windows.Forms.ListBox.ObjectCollection(ListBox1)
    x.Add("test1")
    x.Add("test2")
    x.Add("test3")

    Bei dieser Art und weise wird das Event nicht ein einziges mal gefeuert. Anschließend kann man aber immernoch per ListBox1.Items.Add Einträge hinzufügen, SelectIndex-Wechseln (was übrigens auch ohne Event zu feuern geht:

    Dim x As New Windows.Forms.ListBox.SelectedIndexCollection(ListBox1)

    :D)

    Gruß Floyd


« Zurück  |  Weiter »