myCSharp.de - DIE C# und .NET Community
Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 
 | Suche | FAQ

» Hauptmenü
myCSharp.de
» Startseite
» Forum
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Suche
   » Plugin für Firefox
   » Plugin für IE
   » Gadget für Windows
» Regeln
» Wie poste ich richtig?
» Datenschutzerklärung
» wbb-FAQ

Mitglieder
» Liste / Suche
» Stadt / Anleitung dazu
» Wer ist wo online?

Angebote
» ASP.NET Webspace
» Bücher
» Zeitschriften
   » dot.net magazin
» Accessoires

Ressourcen
» .NET-Glossar
» guide to C#
» openbook: Visual C#
» openbook: OO
» .NET BlogBook
» MSDN Webcasts
» Search.Net

Team
» Kontakt
» Übersicht
» Wir über uns
» Bankverbindung
» Impressum

» Unsere MiniCity
MiniCity
» myCSharp.de Diskussionsforum
Du befindest Dich hier: Community-Index » Diskussionsforum » Knowledge Base » FAQ » [FAQ] Event nur bei Benutzeraktion auslösen, nicht bei programmtechnischer Änderung
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | An Freund senden | Thema zu Favoriten hinzufügen

Antwort erstellen
Zum Ende der Seite springen  

[FAQ] Event nur bei Benutzeraktion auslösen, nicht bei programmtechnischer Änderung

 
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
herbivore
myCSharp.de-Team (Admin)

images/avatars/avatar-2627.gif


Dabei seit: 11.01.2005
Beiträge: 49.024
Entwicklungsumgebung: csc/nmake (nothing is faster)
Herkunft: Berlin


herbivore ist online

[FAQ] Event nur bei Benutzeraktion auslösen, nicht bei programmtechnischer Änderung

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo Community!


Das Problem

Wie kann man erreichen, dass ein Event (z.B. TextBox.TextChanged) nur ausgelöst wird, wenn der Benutzer die Aktion durchführt, nicht aber wenn das Programm die Aktion durchführt.


Die Lösung(en)

Meisten geht es gar nicht darum, dass das Event nicht ausgelöst wird, sondern das eigentliche Ziel ist, dass der eigene Ereignisbehandlungscode - oder Teile davon - nicht ausgeführt werden soll. Dafür gibt es zwei einfache Möglichkeiten.


Boolesche Variable setzen

Die einfachte Lösung ist die Verwendung einer boolschen Variable (z.B. _ignoreEvents, _ignoreTextChanged, _ignoreTextBox1TextChanged, ...) die vor der programmtechnischen Änderung gesetzt und danach zurückgesetzt wird. Am Anfang des EventHandlers fragt man die Variable ab und verlässt ihn, wenn die Variable gesetzt ist. Damit das Zurücksetzen auch im Fehlerfall sauber funktioniert, sollte man es im finally durchführen. Das ist eine einfache, kurze, flexible und elegante Lösung.

C#-Code:
private bool _ignoreEvents = false;

private void DoSomething ()
{
   _ignoreEvents = true;
   try {
      textBox1.Text = "Hallo";
   }
   finally {
      _ignoreEvents = false;
   }
}

protected void textBox1_TextChanged (Object objSender, EventArgs e)
{
   if (_ignoreEvents) { return; }
   // hier die eigentliche Aktion durchführen
}

Natürlich muss man den EventHandler nicht komplett verlassen, sondern kann in Abhängigkeit von der boolschen Variable auch nur Teile ignorieren oder Teile gerade nur dann ausführen, wenn die Änderung programmtechnisch erfolgt (else-Zweig). Man hat also die volle Flexibilität.


Eventhandler deregistrieren

Eine Alternative, die genauso kurz und einfach, jedoch weniger elegant und flexibel ist, wäre den EventHandler temporär zu deregistrieren.

C#-Code:
private void DoSomething ()
{
   textBox1.TextChanged -= textBox1_TextChanged;
   try {
      textBox1.Text = "Hallo";
   }
   finally {
      textBox1.TextChanged += textBox1_TextChanged;
   }
}

protected void textBox1_TextChanged (Object objSender, EventArgs e)
{
   // hier die eigentliche Aktion durchführen
}

Man spart sich dabei zwar die boolsche Variable, dafür kann man aber den EventHander nur ganz oder gar nicht deregistrieren, ist also auch weniger flexibel.


Das Auslösen des Events verhindern

Beide bisher genannten Lösungen wirken nur auf die EventHandler, die man explizit berücksichtigt, also in denen man explizit die boolsche Variable abfragt bzw. die man explizit deregistriert. Das ist - wie gesagt - meistens genau das, was man will. Es ist allerdings auch möglich, das Aufrufen aller EventHander zu verhindern, wenn das Event nach der Empfehlung von Microsoft implementiert wurde. Dazu muss man allerdings die Klasse, die das Event auslöst, überschreiben und dann auch Objekte der Unterklasse verwenden, im folgenden Beispiel also MyTextBoxen statt normalen TextBoxen.

C#-Code:
public class MyTextBox : TextBox
{
   private bool _disableTextChanged = false;

   public bool DisableTextChanged
   {
      get { return _disableTextChanged; }
      set { _disableTextChanged = value; }
   }

   protected override void OnTextChanged (EventArgs e)
   {
      if (_disableTextChanged) { return; }
      base.OnTextChanged (e);
   }
}

...

   private void DoSomething ()
   {
         textBox1.DisableTextChanged = true;
         try {
            textBox1.Text = "Hallo";
         }
         finally {
            textBox1.DisableTextChanged = false;
         }
   }

   protected void textBox1_TextChanged (Object objSender, EventArgs e)
   {
      // hier die eigentliche Aktion durchführen
   }

Noch eine spezielle, dennoch wichtige Anmerkung zum Schluss: Bei dieser letzten Lösung muss man berücksichtigen, das hierdurch nur die EventHandler deaktiviert werden. Die eventauslösende OnTextChanged-Methode wird weiterhin aufgerufen. Für eine Unterklasse von MyTextBox, die OnTextChanged überschreibt statt TextChanged zu abonnieren, sieht es also so aus, als würde das Event immer ausgelöst. Sie müsste also im Zweifel selbst explizit auf DisableTextChanged abfragen. Die Situation könnte man verhindern, indem man die Methode MyTextBox.OnTextChanged sealed macht, was dann aber wiederum die Möglichkeiten der Unterklasse (zu sehr) einschränkt. Im Ergebnis sollte man also lieber eine der erstgenannten Lösungen bevorzugen.


Siehe auch

 [FAQ] Eigenen Event definieren / Information zu Events
 [FAQ] Bestimmte Aktionen bis nach der laufenden GUI-Event-Behandlung verzögern


herbivore
10.07.2009 10:57 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Baumstruktur | Brettstruktur       | Top 
myCSharp.de | Forum Der Startbeitrag ist älter als 5 Jahre.
Der letzte Beitrag ist älter als 5 Jahre.
Antwort erstellen


© Copyright 2003-2014 myCSharp.de-Team. Alle Rechte vorbehalten. 31.10.2014 09:15