web-dev-qa-db-fra.com

Comment passer un événement à une méthode?

J'aimerais créer une méthode qui prenne un événement comme argument et y ajoute eventHandler pour le gérer correctement. Comme ça:

J'ai deux événements:

public event EventHandler Click;
public event EventHandler Click2;

Maintenant, je voudrais passer un événement particulier à ma méthode comme ceci (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);

C'est possible?

J'ai remarqué que ce code fonctionnait bien et je suis retourné à mon projet. J'ai remarqué que lorsque je réussis un événement déclaré dans ma classe, cela fonctionne, mais que lorsque je transmets un événement d'une autre classe, cela ne fonctionne toujours pas.

Ce que je reçois est cette erreur:

L'événement 'System.Windows.Forms.ToolStripItem.Click' peut uniquement apparaître à gauche de + = ou - =

24
Tomasz Smykowski

Ma réponse initiale convenait au sein de la classe qui a défini l'événement, mais vous avez depuis mis à jour votre question pour indiquer que vous souhaitez accomplir cela en dehors de la classe de définition.

Seule la classe qui définit un événement peut faire référence à la variable de délégué implicite utilisée par l'événement. En dehors de cette classe, vous avez uniquement accès aux méthodes add et remove, via += et -=. Cela signifie que vous ne pouvez pas faire ce que vous demandez, directement. Vous pouvez cependant utiliser une approche fonctionnelle.

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

Je l'ai fait comme ça:

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");

Merci à tous pour les conseils. Cette solution ne pourrait être réalisée sans votre aide.

5
Tomasz Smykowski

Il suffit d'écrire tool.Click += Item_Click;

Edit: From MSDN "Les événements ne peuvent être invoqués qu'à partir de la classe ou de la structure où ils sont déclarés". Donc, ce que vous essayez de faire n'est pas possible. Pourriez-vous élaborer davantage sur vos besoins? Pourquoi voudriez-vous passer un événement en tant que paramètre?

2
Petar Minchev

Ce n'est pas possible. Vous pouvez utiliser un délégué au lieu d'un événement si cela répond à vos besoins.

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

Votre question suggère que vous vous êtes trompé dans certains mécanismes: Vous ne pouvez pas passer des événements!

Vous souhaiterez probablement passer une fonction en tant que paramètre, de sorte que la méthode appelante appellera cette autre méthode à un moment donné. En termes techniques, il s'agit d'un délégué. Je suggère d'utiliser la classe Action déjà définie. Voici un exemple d'extrait de code:

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

La bonne chose à ce propos est que lorsque vous appelez MyFunction, vous pouvez déclarer l'action à l'aide de la syntaxe inline:

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