views:

174

answers:

5

I would like to create a method that takes as a argument an event an adds eventHandler to it to handle it properly. Like this:

I have 2 events:

public event EventHandler Click;
public event EventHandler Click2;

Now i would like to pass particular event to my method like this (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);

Is it possible or do I not understand it good?

Edit: I've noticed with help of you that this code worked fine, and returned to my project and noticed that when I pass event declared in my class it works, but when I pass event from other class id still does not work. Updated above example to reflect this issue.

What I get is this error:

The event 'System.Windows.Forms.ToolStripItem.Click' can only appear on the left hand side of += or -=

+1  A: 

Just write tool.Click += Item_Click;

Edit: From MSDN "Events can only be invoked from within the class or struct where they (it) are declared". So what you are trying to do is not possible. Could you elaborate more on your needs? Why would you want to pass an event as a parameter?

Petar Minchev
Oh.. so my code ies bad elsewhere. Thank you!
tomaszs
It's not minus from me. Your answer was first and correct one. I've tried longer version of this code and it didn't want to work. I've wrote this question here to ask for help, but when after you answer I've rechecked this simple example from here it occurred to be correct as you wrote. Thanks .
tomaszs
Still have a problem. Sorry for missasking question, not it's pricese and focuses on the situation when i have a error
tomaszs
I can't do it because I want attaching to a Click event be in AttachToHandleEvent
tomaszs
It was in response to your original answer: "I don't see a problem, the code is semantically correct. Edit: You asked is it possible. Just try it:). It would have taken less time to try it, than to ask here."
Jamie Ide
@Jamie Ide - Please notice "Edit" at the end of my question please, ok?
tomaszs
The code isn't semantically correct (you can't pass an event as an argument) and the rest of the answer wasn't helpful. Heck, if people tried things for themselves this site wouldn't need to exist.
Jamie Ide
@Petar Minchev - Your answer was wrong for gods sake. Please read carefully my v2 question and answer that i put here and stop making this uncomfortable situation. I did give you a plus point, but I see I need to rethink it again.
tomaszs
@Jamie Ide - Yeah. You can't pass event but as you can see here: http://stackoverflow.com/questions/2560258/how-to-pass-event-to-method/2560605#2560605 you can using workaround. It's so hard to read all answers here? If people would read answers empty discussions like this would not need to exist
tomaszs
After alll thank you everyone for engagement in helping me with this issue. Without your help I couldn't find a good solution. Bye.
tomaszs
@tomoszs - I downvoted the answer based on the question and answer at the time I ansered it (about 6 hours ago). Before multiple edits and before the answer you linked to. Feel free to downvote my answer if it will make you feel better. This isn't an empty discussion, it's a great example of why voting is anonymous and voters should stay anonymous. I've learned my lesson.
Jamie Ide
@Jamie Ide If you feel offended by this discussion than sorry. I didn't intend to do that. I did not downvote your answer. More over I think it has a very important part of whole solution so I gave you upvote now.
tomaszs
I'm not about to be offended by someone who looks like a silly pastel unicorn.
Jamie Ide
@tomaszs and Jamie Ide: I apologize guys, I was in a bad mood. I will delete my stupid comments above.
Petar Minchev
+2  A: 

My original answer was suitable from within the class that defined the event, but you've since updated your question to reflect that you wish to accomplish this from outside the defining class, so I've stricken that.

Only the class that defines an event can refer to the implicit delegate variable that the event uses. From outside that class, you only have access to the add and remove methods, via += and -=. This means that you can't do what you're asking, directly. You can, however, use a functional approach.

class A{
    public event EventHandler Event1;
    public event EventHandler Event2;

    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();
    }
}
P Daddy
i've checked it for updated version of my problem and unfortunately it does not work, can you help me?
tomaszs
+2  A: 

It's not possible. You can use a delegate instead of an event if that meets your needs.

Jamie Ide
A: 
    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);
    }
thelost
+1  A: 

I did it like this:

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

Thank you all for advice. This solution could not be done without your help.

tomaszs