webentwicklung-frage-antwort-db.com.de

Wie übergebe ich ein Ereignis an eine Methode?

Ich möchte eine Methode erstellen, die ein Ereignis als Argument annimmt und ihm eventHandler hinzufügt, um es richtig zu behandeln. So was:

Ich habe zwei Ereignisse:

public event EventHandler Click;
public event EventHandler Click2;

Jetzt möchte ich meiner Methode ein bestimmtes Ereignis übergeben (Pseudocode):

public AttachToHandleEvent(EventHandler MyEvent)
{
    MyEvent += Item_Click;
}

private void Item_Click(object sender, EventArgs e)
{
    MessageBox.Show("lalala");
}

ToolStripMenuItem tool = new ToolStripMenuItem();
AttachToHandleEvent(tool.Click);

Ist es möglich?

Ich habe festgestellt, dass dieser Code gut funktioniert hat, und bin zu meinem Projekt zurückgekehrt. Wenn ich ein in meiner Klasse deklariertes Ereignis übergebe, funktioniert es, aber wenn ich ein Ereignis von einer anderen Klasse übergebe, funktioniert es immer noch nicht.

Was ich bekomme, ist dieser Fehler:

Das Ereignis 'System.Windows.Forms.ToolStripItem.Click' kann nur links von + = oder - = angezeigt werden

24

Meine ursprüngliche Antwort war innerhalb der Klasse, in der das Ereignis definiert wurde, geeignet, aber Sie haben Ihre Frage seitdem aktualisiert, um zu berücksichtigen, dass Sie dies von außerhalb der definierenden Klasse erreichen möchten.

Nur die Klasse, die ein Ereignis definiert, kann sich auf die implizite Delegatvariable beziehen, die das Ereignis verwendet. Außerhalb dieser Klasse haben Sie nur über += und -= Zugriff auf die Methoden add und remove. Das bedeutet, dass Sie das, was Sie möchten, nicht direkt ausführen können. Sie können jedoch einen funktionalen Ansatz verwenden.

class A{
    public event EventHandler Event1;

    public void TriggerEvent1(){
        if(Event1 != null)
            Event1(this, EventArgs.Empty);
    }
}

class B{
    static void HandleEvent(object o, EventArgs e){
        Console.WriteLine("Woo-hoo!");
    }

    static void AttachToEvent(Action<EventHandler> attach){
        attach(HandleEvent);
    }

    static void Main(){
        A a = new A();
        AttachToEvent(handler=>a.Event1 += handler);
        a.TriggerEvent1();
    }
}
24
P Daddy

Ich habe es so gemacht:

public AttachToHandleEvent(Object obj, string EventName)
{
    EventInfo mfi = obj.GetType().GetEvent(EventName);
    MethodInfo mobj = mfi.GetAddMethod();
    mobj.Invoke(obj, new object[] { Item_Click});
}

private void Item_Click(object sender, EventArgs e)
{
    MessageBox.Show("lalala");
}

ToolStripMenuItem tool = new ToolStripMenuItem();
AttachToHandleEvent(tool "Click");

Vielen Dank für den Rat. Diese Lösung ist ohne Ihre Hilfe nicht möglich.

5

Schreibe einfach tool.Click += Item_Click;

Bearbeiten: Aus MSDN "Ereignisse können nur von der Klasse oder Struktur aus aufgerufen werden, in der sie deklariert werden". Was Sie also zu tun versuchen, ist nicht möglich. Könnten Sie mehr auf Ihre Bedürfnisse eingehen? Warum möchten Sie ein Ereignis als Parameter übergeben?

2
Petar Minchev

Es ist nicht möglich. Sie können einen Delegaten anstelle eines Ereignisses verwenden, wenn dies Ihren Anforderungen entspricht.

2
Jamie Ide
    delegate void doIt(object sender, object data);
    event doIt OnDoIt;

    void add(doIt theDel)
    {
        OnDoIt += theDel;
    }

    void doIt1(object a, object b)
    {
    }

    void doIt2(object a, object b)
    {
    }

    void add()
    {
        add(doIt1);
        add(doIt2);
    }
1
thelost

Ihre Frage legt nahe, dass Sie einige Mechanismen falsch verstanden haben: Sie können keine Ereignisse passieren!

Wahrscheinlich möchten Sie eine Funktion als Parameter übergeben, daher ruft die aufrufende Methode die andere Methode irgendwann auf. Technisch gesehen ist dies ein Delegierter. Ich empfehle die Verwendung der bereits definierten Action-Klasse. Hier ist ein Beispielausschnitt:

void MyFunction (string otherArguments, Action onFinished){
    ...
    if (onFinished != null)
        onFinished.Invoke();
}

Das Schöne daran ist, dass Sie beim Aufruf von MyFunction die Action mit der Inline-Syntax deklarieren können:

MyFunction("my other argument", ()=>{
    ///do stuff here, which will be execuded when the action is invoked
});
0
Radu Simionescu

Ich übergebe Funktionen/Methoden (anstelle von Ereignissen) wie folgt:

class A
{
    public void something()
    {
        var myAction = 
            new Action<object, object>((sender, evArgs) => {
                MessageBox.Show("hiii, event happens " + (evArgs as  as System.Timers.ElapsedEventArgs).SignalTime); 
            });
        B.timer(myAction);
    }
}

class B
{
    public static void timer( Action<object, System.Timers.ElapsedEventArgs> anyMethod)
    {
        System.Timers.Timer myTimer = new System.Timers.Timer();
        myTimer.Elapsed += new System.Timers.ElapsedEventHandler(anyMethod);
        myTimer.Interval = 2000;
        myTimer.Start();
    }
}
0
T.Todua