permite centrarse en ProjectAdded
caso (aunque problema descrito es exactamente el mismo para el resto de los eventos).
El ejemplo de código que ha mostrado intenta registrar el controlador SolutionEvents_ProjectAdded
para el evento ProjectAdded
. Sin embargo, el objeto SolutionEvents
que expone el evento, tiene un alcance vitalicio limitado al cierre de su método de envoltura (no ha mostrado su firma, llamémoslo Connect
). Después de que el flujo de control había dejado que alcance, objeto local ya ha sido basura recogida, por lo que su evento nunca se llama:
código roto:
public class Connector
{
public void Connect()
{
((Events2)dte.Events).SolutionEvents.ProjectAdded += SolutionEvents_ProjectAdded;
}
void SolutionEvents_ProjectAdded()
{
// callback is dead
}
}
Para corregir esto, es necesario asignar el SolutionEvents
objetar a alguna variable, cuya duración abarca el controlador SolutionEvents_ProjectAdded
, por ejemplo sobre toda la clase de envoltura. En el siguiente ejemplo, el alcance se extiende sobre toda el tipo (llamémoslo Connector
), y asegura que el controlador es accesible durante la vida útil de ese tipo:
código fijo:
public class Connector
{
SolutionEvents _solutionEvents;
public void Connect()
{
_solutionEvents = ((Events2)dte.Events).SolutionEvents;
_solutionEvents.ProjectAdded += SolutionEvents_ProjectAdded;
}
void SolutionEvents_ProjectAdded()
{
// callback works
}
}
Para ser más precisos, comprobar esta referencia MSDN - Scoping Variables Appropriately in Event Handlers:
un error común en los controladores de eventos de programación está conectando el controlador de eventos a un objeto que ha sido declarado w con un alcance demasiado limitado con el fin de manejar el evento. El objeto debe tener una vida que abarque no solo la función que conecta el método de devolución de llamada como un controlador de eventos del objeto, sino también a través del método de devolución de llamada donde se maneja realmente el evento.De lo contrario, si el objeto está fuera del alcance y ya no está definido en el método de devolución de llamada , no se llama al método de devolución de llamada y el evento no se maneja como según se desee.
¿Qué es '_hSolutionEvents' en' Initialize() '? –
¡Tiene razón, actualizó el código! Pensé en '_HSolutionEvents' que se necesita para' UnadviseSolutionEvents' y también agregué el nuevo código. Es una pena que no haya mucha información sobre cómo hacer complementos para la mejor DevTool ... – FooBarTheLittle