2008-09-20 4 views
12

Ist es unter Umständen möglich, dies zu erreichen?C# -Ereignisse von außerhalb der besitzenden Klasse aufrufen?

Meine aktuellen Umstände sind dies:

public class CustomForm : Form 
{ 
    public class CustomGUIElement 
    { 
    ... 
     public event MouseEventHandler Click; 
     // etc, and so forth. 
    ... 
    } 

    private List<CustomGUIElement> _elements; 

    ... 

    public void CustomForm_Click(object sender, MouseEventArgs e) 
    { 
     // we might want to call one of the _elements[n].Click in here 
     // but we can't because we aren't in the same class. 
    } 
} 

Mein erster Gedanke eine Funktion ähnlich zu haben war:

internal enum GUIElementHandlers { Click, ... } 
internal void CustomGUIElement::CallHandler(GUIElementHandler h, object[] args) { 
    switch (h) { 
     case Click: 
      this.Click(this, (EventArgs)args[0]); 
      break; 
     ... // etc and so forth 
    } 
} 

Es ist ein schrecklich hässlich Flickschusterei, aber es sollte funktionieren ... Es muss eine elegantere Lösung sein? Die .NET-Bibliothek tut dies die ganze Zeit mit Nachrichtenhandlern und aufrufenden Ereignissen in Controls. Hat noch jemand andere/bessere Ideen?

Antwort

24

Sie müssen nur eine öffentliche Methode zum Aufrufen des Ereignisses hinzufügen. Microsoft tut dies bereits für einige Ereignisse wie PerformClick für Steuerelemente, die ein Click Ereignis offen legen.

public class CustomGUIElement  
{ 
    public void PerformClick() 
    { 
     OnClick(EventArgs.Empty); 
    } 

    protected virtual void OnClick(EventArgs e) 
    { 
     if (Click != null) 
      Click(this, e); 
    } 
} 

Sie würden die folgenden in Ihrem Beispiel Ereignishandler dann tun ...

public void CustomForm_Click(object sender, MouseEventArgs e)   
{ 
    _elements[0].PerformClick(); 
} 
+1

Ich glaube, er hat die Veranstaltung von außerhalb der Event-Klasse angesprochen? –

+1

Sie rufen PerformClick() von außerhalb der Ereignisklasse auf. –

+0

Nein, das ist die Art von Ding, die ich suchen wollte; dh. Aufruf der Veranstaltung von außerhalb der Klasse der Veranstaltung. Ich habe nur gehofft, dass es einen Weg gibt, die Methode zu vermeiden. Ich nehme an, ich gehe mit der internen Lösung, die ich gepostet habe, dieses benutzerdefinierte Formular wird in einer DLL sein, so dass die internen Sachen versteckt werden. –

1

Sie sollten den Code, den Sie in einer Methode von außen ausführen möchten, wirklich umbrechen. Diese Methode kann dann tun, was auch immer Ihr Ereignis tun würde - und dieses Ereignis würde stattdessen auch diese Methode aufrufen.

+0

Es würde funktionieren. Schlecht, aber es würde funktionieren. Eine Liste von Callbacks zu speichern, ist im Grunde das, was ein Event ohnehin macht. Warum sollte man sich bemühen, das, was schon da ist, neu zu implementieren? –

7

Die Veranstaltung Schlüsselwort in C# ändert die Erklärung des Delegierten. Es verhindert die direkte Zuweisung an den Delegaten (Sie können nur + = und - = für ein Ereignis verwenden) und es verhindert den Aufruf des Delegaten von außerhalb der Klasse.

So könnten Sie Ihren Code ändern, wie folgt aussehen:

public class CustomGUIElement 
{ 
... 
    public MouseEventHandler Click; 
    // etc, and so forth. 
... 
} 

Dann können Sie das Ereignis von außerhalb der Klasse wie folgt aufrufen.

myCustomGUIElement.Click(sender,args); 

Der Nachteil ist, dass Code, der die Klasse verwendet, kann sehr leicht, wie dies mit dem Code alle registrierten Handler überschreiben:

myCustomGUIElement.Click = null; 

was nicht erlaubt ist, wenn das Click-Delegierten als ein Ereignis deklariert wird.

+0

Ich hatte nicht so darüber nachgedacht. Die andere Antwort ist noch praktischer, aber danke für die Einsicht. –

+0

Diese Antwort möchte ich lernen. Danke @Lee – uzay95