Позволяет сосредоточиться на событии ProjectAdded
(хотя описанная проблема точно такая же для остальных событий).
Пример кода, который вы показали, пытается зарегистрировать обработчик SolutionEvents_ProjectAdded
для события ProjectAdded
. Однако объект SolutionEvents
, представляющий событие, имеет область действия, ограниченную закрытием его метода упаковки (вы не показали его сигнатуру - назовем его Connect
). После того, как поток управления покинул эту область, локальный объект уже был собран сборщиком мусора, поэтому его событие никогда не вызывается:
Сломанный код:
public class Connector
{
public void Connect()
{
((Events2)dte.Events).SolutionEvents.ProjectAdded += SolutionEvents_ProjectAdded;
}
void SolutionEvents_ProjectAdded()
{
// callback is dead
}
}
Чтобы это исправить, вам нужно присвоить объект SolutionEvents
некоторой переменной, время жизни которой охватывает обработчик SolutionEvents_ProjectAdded
- например, по всему классу упаковки. В приведенном ниже примере область действия распространяется на весь тип (назовем его Connector
) и обеспечивает доступность обработчика в течение времени жизни этого типа:
Фиксированный код:
public class Connector
{
SolutionEvents _solutionEvents;
public void Connect()
{
_solutionEvents = ((Events2)dte.Events).SolutionEvents;
_solutionEvents.ProjectAdded += SolutionEvents_ProjectAdded;
}
void SolutionEvents_ProjectAdded()
{
// callback works
}
}
Чтобы быть более точным, проверьте этот справочник MSDN - Соответствующие переменные области видимости в обработчиках событий :
Распространенной ошибкой в программировании обработчиков событий является подключение события
обработчик объекта, который был объявлен с слишком ограниченной областью действия
с целью обработки события. У объекта должна быть жизнь
который охватывает не только функцию, которая соединяет обратный вызов
Метод как обработчик события объекта, но также и через обратный вызов
сам метод, где событие фактически обрабатывается. В противном случае, если
объект находится вне области видимости и больше не определяется в обратном вызове
метод, метод обратного вызова не вызывается и событие не обрабатывается
по желанию.