Подтвердить что ты не робот

Как передать событие методу?

Я хотел бы создать метод, который принимает событие в качестве аргумента и добавляет eventHandler к нему для правильной обработки. Вот так:

У меня два события:

public event EventHandler Click;
public event EventHandler Click2;

Теперь я хотел бы передать конкретное событие моему методу, подобному этому (псевдокод):

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

Возможно ли это?

Я заметил, что этот код работал нормально и вернулся к моему проекту и заметил, что когда я передаю событие, объявленное в моем классе, оно работает, но когда я передаю событие из другого класса, он все равно не работает.

Я получаю эту ошибку:

Событие 'System.Windows.Forms.ToolStripItem.Click' может появляться только с левой стороны of + = или - =

4b9b3361

Ответ 1

Мой первоначальный ответ был подходящим из класса, который определил событие, но с тех пор вы обновили свой вопрос, чтобы отразить, что вы хотите выполнить это из-за пределов определяющего класса, поэтому я поразил это.

Только класс, определяющий событие, может ссылаться на неявную переменную делегата, которую использует событие. Извне этого класса вы получаете доступ только к методам add и remove через += и -=. Это означает, что вы не можете делать то, что вы просите, напрямую. Однако вы можете использовать функциональный подход.

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();
    }
}

Ответ 2

Я сделал это вот так:

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

Спасибо всем за советы. Это решение не может быть выполнено без вашей помощи.

Ответ 3

Это невозможно. Вы можете использовать делегат вместо события, если это соответствует вашим потребностям.

Ответ 4

Просто напишите tool.Click += Item_Click;

Изменить: из MSDN "События могут быть вызваны только из класса или структуры, где они объявлены". То, что вы пытаетесь сделать, невозможно. Не могли бы вы подробнее рассказать о своих потребностях? Почему вы хотите передать событие в качестве параметра?

Ответ 5

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

Ответ 6

Ваш вопрос подсказывает, что у вас есть некоторые механизмы: Вы не можете передавать события!

Вы, скорее всего, хотите передать функцию в качестве параметра, поэтому вызывающий метод вызовет этот другой метод в какой-то момент. В техническом плане это делегат. Я предлагаю использовать уже определенный класс Action. Вот пример фрагмента:

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

Приятная вещь в том, что при вызове MyFunction вы можете объявить действие с помощью встроенного синтаксиса:

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