Rainer's profileCyrons BlogPhotosBlogListsMore Tools Help

Blog


    April 21

    EventArgs mit Hintergrundbeleuchtung


    private void
    button1_Click(object sender, EventArgs e)
    
    

    Wie oft habe ich das schon gesehen! Mit der EventArgs-Klasse ist es allerdings nicht ganz so einfach, weil sie auf den ersten Blick wie eine Kuriosität wirkt. Sie ist nämlich eine Basisklasse mit nur einem öffentlichen Member - und der erscheint auch noch wenig sinnvoll. Schauen wir uns an, was die EventArgs-Klasse bietet:

    class EventArgsTest : EventArgs
       {
          // Von der EventArgs-Klasse kann nichts geerbt werden.
          // Die einzigen überschreibbaren Objekte stammen aus der Superklasse Object!
          public override bool Equals(object obj)
          {
             return base.Equals(obj);
          }
          public override int GetHashCode()
          {
             return base.GetHashCode();
          }
          public override string ToString()
          {
             return base.ToString();
          }
       }
    
       static class TestClass
       {
          public static void TestMethod()
          {
             /* Das Einzige Objekt das EventArgs anbietet, ist eine statische readonly Variable
              * vom Typ EventArgs, und die ist auch noch leer! */
    
             // Beide Variablen sind inhaltlich identisch:
             var test = EventArgs.Empty;
             EventArgs test2 = new EventArgs();         
          }
       }

    Wie sie sehen, sehen sie nichts. Tatsächlich ist EventArgs bis auf die Variable "Empty" leer! Was soll das?
    Gehen wir zurück zum ButtonClickEvent und schauen wir uns den Parameter e genauer an:

    Type typeTest = e.GetType();

    ergibt, daß e vom Typ MouseEventArgs ist.

    Der Hintergrund:
    Alle Control-Events werden vom .net-Delegat EventHandler transportiert. Das wird sofort ersichtlich, wenn man sich den Form-Designer-Code anschaut. Im Button-Abschnitt z.B. findet man das ClickEvent-Abo:

    this.button1.Click += new System.EventHandler(this.button1_Click);

    Damit dieser Delegat möglichst flexibel eingesetzt werden kann, erwartet er als Parametertypen object und EventArgs . Über object sender können z.B. beliebige Klasseninstanzen bzw. this übergeben werden und über EventArgs e alle Klassen die von EventArgs erben.
    Das ist also des Pudels Kern! Ohne die Basisklasse EventArgs wäre so ein Casting gar nicht möglich und der Delegat EventHandler würde seine ganze Flexibilität einbüßen!

    Fazit:
    In einer EventHandler-Methode kann e nicht unmittelbar ausgewertet werden. Zuerst muß auf den richtigen Typen gecastet werden.
    Beispiel:

    MouseEventArgs test = (MouseEventArgs)e;
    // Jetzt kommt man an alle Objekte, die MouseEventArgs zu bieten hat.
    // Zum Beispiel:
    System.Drawing.Point p = test.Location;

    oder so:

    MouseEventArgs test = e as MouseEventArgs;
    System.Drawing.Point p = test.Location;
    ...ist das Gleiche in grün. ;-)
    April 20

    Buchempfehlung "Head first Design Patterns" oder "Entwurfsmuster von Kopf bis Fuß"

    Wer "OOP" sagt, muß auch "Design Patterns" sagen. Dazu kann ich "Entwurfsmuster von Kopf bis Fuß" (wer lieber die englische Variante mag: "Head first Design Patterns") wärmstens empfehlen (Verlag: O'Reilly). Das Ding ist zwar für Java geschrieben, aber die Sprache unterscheidet sich syntaktisch kaum von C#, ist also keinerlei Hürde.

    1. Für Resourcen-Referenzierung wird in Java statt "using" das Schlüsselwort "import" benutzt.
    2. Interfaces werden in C# einfach über einen Doppelpunkt implementiert. In Java wird das Schlüsselwort "implements" benutzt.
    3. Klassenvererbung geschieht in Java über das Schlüsselwort "extends" statt über einen Doppelpunkt.

    Das ist eigentlich schon alles, was der C#-Entwickler braucht, um die Java-Codes im Buch zu verstehen.
    Es gibt aber mindestens drei gravierende (mir bekannte) Sprachunterschiede:

    1. In C# gibt es keine Mehrfachvererbung. Darum funktioniert das im Buch beschriebene Decorator-Pattern so nicht. Es gibt aber genügend Beispiele im Netz für die .net- bzw. C#-Variante. Eine gute Seite mit Pattern-Demos: http://www.dofactory.com/Default.aspx
    2. In Java scheint es das Schlüsselwort "override" nicht zu geben. Darum müssen einige Beispiele im Buch für C# entsprechend angepasst werden, indem dieses Schlüsselwort nachträglich eingepflanzt wird.
    3. In den .net-Sprachen wurde das Observer-Pattern durch Events ersetzt. Dieses Kapitel kann man als C#-Entwickler also überspringen.

    Die Beispiele sind bewußt einfach gehalten, sehr anschaulich und beschränken sich auf das Wesentliche. Darum ist es auch für Einsteiger besonders gut geeignet. Das inhaltliche Design des Buches entspricht ganz dem gewohnten (und mir außerordentlich gut gefallenden) Head First-Stil. Wer sich noch nicht zum Kauf entscheiden kann, sollte mal einen Blick in die Vorschau bei Google books werfen:
    http://books.google.de/books?id=k4_7uAJrwkEC&printsec=frontcover#PPR1,M1