У меня была аналогичная путаница и, честно говоря, найти ответы здесь, чтобы ввести в заблуждение. Хотя пара намекала на решения, которые я позже найду, будет работать.
Мое решение заключалось в том, чтобы попасть в книги и стать более знакомыми с делегатами и обработчиками событий. Хотя я использовал оба в течение многих лет, я никогда не был знаком с ними. http://www.codeproject.com/Articles/20550/C-Event-Implementation-Fundamentals-Best-Practices дает лучшее объяснение как делегатов, так и обработчиков событий, которые я когда-либо читал, и ясно объясняет, что класс может быть издателем событий и использовать другие классы. В этой статье: http://www.codeproject.com/Articles/12285/Implementing-an-event-which-supports-only-a-single обсуждается, как однократные события обрабатываются только одним обработчиком, поскольку делегаты являются многоадресными по определению. Делегат наследует system.MulticastDelegate большинство, включая делегатов системы, являются многоадресными. Я обнаружил, что многоадресная рассылка означает, что любой обработчик событий с той же подписью получит поднятое событие. Многоадресное поведение вызвало у меня несколько бессонных ночей, когда я шагнул через код и увидел, что мое событие, казалось бы, ошибочно отправлено обработчикам, что я не собирался получать это событие. Обе статьи объясняют это поведение. Вторая статья показывает вам один путь, и первая статья показывает вам другую, сделав делегата и подпись жестко напечатанной. Я лично считаю, что сильная типизация предотвращает глупые ошибки, которые могут быть причиной боли. Поэтому я проголосовал за первую статью, хотя я получил второй код статьи. Мне было просто любопытно. :-)
Мне также было любопытно, могу ли я получить код статьи №2, чтобы вести себя так, как я интерпретировал исходный вопрос выше. Независимо от выбранного вами подхода или если я также неправильно истолковываю исходный вопрос, мое настоящее сообщение состоит в том, что я все еще думаю, что вам будет полезно прочитать первую статью, как и я, особенно если вопросы или ответы на этой странице оставят вас в замешательстве. Если у вас многодневные кошмары и вам нужно быстрое решение, вам может помочь статья 2.
Я начал играть со классом eventRaiser второй статьи. Я сделал простой проект в виде окон. Я добавил в свой проект второй класс статей EventRaiser.cs. В коде главной формы, я определил ссылку на этот EventRaiser класс на вершине, как
private EventRaiser eventRaiser = new EventRaiser();
я добавил метод в основной форме кода, который я хотел бы назвать, когда событие был уволен
protected void MainResponse(object sender, EventArgs eArgs)
{
MessageBox.Show("got to MainResponse");
}
затем в конструкторе главной формы я добавил назначение события:
eventRaiser.OnRaiseEvent += new EventHandler(MainResponse);`
затем я создал класс, который должен быть создан с помощью моей главной формы, которая называется «Si mpleClass "из-за отсутствия творческой изобретательности на данный момент.
Затем я добавил кнопку, и в случае щелчка данной кнопки я инстанцирован код SimpleClass Я хотел поднять событие из:
private void button1_Click(object sender, EventArgs e)
{
SimpleClass sc = new SimpleClass(eventRaiser);
}
Примечания экземпляра «eventRaiser», который я прошел в SimpleClass.cs , Это было определено и инстанцировано ранее в коде главной формы.
В SimpleClass:
using System.Windows.Forms;
using SinglecastEvent; // see SingleCastEvent Project for info or http://www.codeproject.com/Articles/12285/Implementing-an-event-which-supports-only-a-single
namespace GenericTest
{
public class SimpleClass
{
private EventRaiser eventRaiser = new EventRaiser();
public SimpleClass(EventRaiser ev)
{
eventRaiser = ev;
simpleMethod();
}
private void simpleMethod()
{
MessageBox.Show("in FileWatcher.simple() about to raise the event");
eventRaiser.RaiseEvent();
}
}
}
Единственный момент, к частному методу я назвал SimpleMethod было проверить, что в частном области видимости метод может еще поднять событие, не то, что я сомневалась, но мне нравится быть положительны.
Я запустил проект, и это привело к тому, что событие «SimpleMethod» из «SimpleClass» было перенесено на основную форму и перешло к ожидаемому правильному методу MainResponse, доказывая, что один класс действительно может поднять событие, которое потребляется другим классом. Да, событие должно быть поднято из класса, который нуждается в его трансляции для других классов, которым это необходимо. Прием классов может быть одним классом или многими многими классами в зависимости от того, насколько сильно вы набрали их, или сделав их одиночными, как в 2-й статье.
Надеюсь, что это поможет, а не грязь в воде. Лично у меня есть много делегатов и событий для очистки! Многоадресные демоны бегут!
Этих старый пост поднимает вопрос, который можно легко обойти с помощью концентратора событий, как [TinyMessenger ] (https://github.com/grumpydev/TinyMessenger). – Larry 2017-04-07 09:49:27