2015-04-26 3 views
6

Используя Microsoft.Vbe.Interop в C#, я могу получить доступ к CommandBarEvents и ReferencesEvents через VBE.Events.Где VBProjectsEvents?

Однако, когда-либо так полезная документация MSDN, по-видимому, указывает, что есть VBProjectsEvents, который я мог бы использовать для уведомления моей надстройки, когда проект добавлен или удален в/из VBE ... что именно то, м, пытающихся достичь здесь.

Я могу видеть, что _VBProjectsEvents интерфейс в браузере объектов , но не выполнение для него (в отличие от интерфейса _CommandBarControlsEvents, который реализуется с помощью CommandBarEventsClass), с помощью ReSharper-х перейти к реализации функции.

Есть ли реализация интерфейса _VBProjectsEvents где угодно? Если нет, то как один из них уведомляется об удалении VBProject из среды IDE?

ответ

2

Для этих событий необходимо создать мойку .

Реализовать интерфейс _dispVBProjectsEvents доставки - вот реализация, которая реагирует на эти события, вызывая регулярные управляемые .net события, эффективно «обертка» в VBProjects событии:

public class VBProjectsEventsSink : _dispVBProjectsEvents 
{ 
    public event EventHandler<DispatcherEventArgs<VBProject>> ProjectAdded; 
    public void ItemAdded(VBProject VBProject) 
    { 
     if (VBProject.Protection == vbext_ProjectProtection.vbext_pp_none) 
     { 
      OnDispatch(ProjectAdded, VBProject); 
     } 
    } 

    public event EventHandler<DispatcherEventArgs<VBProject>> ProjectRemoved; 
    public void ItemRemoved(VBProject VBProject) 
    { 
     if (VBProject.Protection == vbext_ProjectProtection.vbext_pp_none) 
     { 
      OnDispatch(ProjectRemoved, VBProject); 
     } 
    } 

    public event EventHandler<DispatcherRenamedEventArgs<VBProject>> ProjectRenamed; 
    public void ItemRenamed(VBProject VBProject, string OldName) 
    { 
     var handler = ProjectRenamed; 
     if (handler != null && VBProject.Protection == vbext_ProjectProtection.vbext_pp_none) 
     { 
      handler.Invoke(this, new DispatcherRenamedEventArgs<VBProject>(VBProject, OldName)); 
     } 
    } 

    public event EventHandler<DispatcherEventArgs<VBProject>> ProjectActivated; 
    public void ItemActivated(VBProject VBProject) 
    { 
     if (VBProject.Protection == vbext_ProjectProtection.vbext_pp_none) 
     { 
      OnDispatch(ProjectActivated, VBProject); 
     } 
    } 

    private void OnDispatch(EventHandler<DispatcherEventArgs<VBProject>> dispatched, VBProject project) 
    { 
     var handler = dispatched; 
     if (handler != null) 
     { 
      handler.Invoke(this, new DispatcherEventArgs<VBProject>(project)); 
     } 
    } 
} 

DispatcherEventArgs класса просто удобный способ разоблачить VBProject элемент связан с событием, и он может быть повторно использован для других раковин:

public class DispatcherEventArgs<T> : EventArgs 
    where T : class 
{ 
    private readonly T _item; 

    public DispatcherEventArgs(T item) 
    { 
     _item = item; 
    } 

    public T Item { get { return _item; } } 
} 

клиентский код должен зарегистрировать раковину - и для что вы должны держать IConnectionPoint поле и его int печенье:

private readonly IConnectionPoint _projectsEventsConnectionPoint; 
private readonly int _projectsEventsCookie; 

VBProjects коллекция реализует интерфейс IConnectionPointContainer, который необходимо использовать для найти точку подключения:

var sink = new VBProjectsEventsSink(); 
var connectionPointContainer = (IConnectionPointContainer)_vbe.VBProjects; 
var interfaceId = typeof (_dispVBProjectsEvents).GUID; 
connectionPointContainer.FindConnectionPoint(ref interfaceId, out _projectsEventsConnectionPoint); 

После того как вы используйте IConnectionPoint, используйте метод Advise, чтобы «подключить» вашу раковину и получить cookie:

_projectsEventsConnectionPoint.Advise(sink, out _projectsEventsCookie); 

И тогда вы можете справиться с раковиной событий, как вы бы любое «нормальное» .net событие:

sink.ProjectAdded += sink_ProjectAdded; 
sink.ProjectRemoved += sink_ProjectRemoved; 
sink.ProjectActivated += sink_ProjectActivated; 
sink.ProjectRenamed += sink_ProjectRenamed; 

Если вы хотите отключить раковину, вы передаете печенье методы Unadvise из IConnectionPoint например: "Простой, как"

_projectsEventsConnectionPoint.Unadvise(_projectsEventsCookie); 

+0

Знаете ли вы о каких-либо событиях для отслеживания открытия и закрытия объектов CodePane? Я разместил здесь новый вопрос: [Событие возникло при закрытии или открытии CodePane] (https://stackoverflow.com/q/44391917/154439). – mwolfe02