| Author: |
Carlos J. Quintero (Microsoft MVP) |
Applies to: |
Microsoft Visual Studio 2005 |
| Date: |
March 2008 |
|
Microsoft Visual Studio 2008 |
| Updated: |
March 2013 |
|
Microsoft Visual Studio 2010 |
| |
|
|
Microsoft Visual Studio 2012 |
Introduction
This article explains why the EnvDTE80.CodeModelEvents class does not fire the
ElementAdded, etc. events.
More Information
Visual Studio 2005 introduced the new EnvDTE80 namespace which provides the
EnvDTE80.CodeModelEvents class with the ElementAdded, ElementChanged and
ElementDeleted events. To get an instance of this class, you have to cast the
DTE2.Events property to the EnvDTE80.Events2 type, which provides the
CodeModelEvents property. However, when you do this and test it adding a
function to a class, the ElementAdded event is not fired. This is due to an
optimization performed by the Visual Studio team: to avoid firing events each
time that the code model changes (which can be really often) when maybe nobody
is listening to them, events are not fired unless you have traversed the code
elements before subscribing to the event. The add-in below shows the code needed
to get code model events of the first project of a solution. If you can load the
add-in when a solution is loaded with a project, and add a new function to an
existing class, you will notice that you receive the ElementAdded event, but if
you remove the NavigateCodeElements function and repeat the test, the event is
not fired.
Option Strict On
Imports System
Imports Extensibility
Imports EnvDTE
Imports EnvDTE80
Imports System.Windows.Forms
Public Class Connect
Implements IDTExtensibility2
Private m_objDTE2 As DTE2
Private WithEvents m_objCodeModelEvents As EnvDTE80.CodeModelEvents
Public Sub OnConnection(ByVal Application As Object, ByVal ConnectMode As Extensibility.ext_ConnectMode, ByVal AddInInst As Object, _
ByRef custom As System.Array) Implements Extensibility.IDTExtensibility2.OnConnection
Dim objEvents2 As EnvDTE80.Events2
Select Case ConnectMode
Case ext_ConnectMode.ext_cm_AfterStartup, ext_ConnectMode.ext_cm_Startup
m_objDTE2 = DirectCast(Application, DTE2)
If m_objDTE2.Solution.Projects.Count > 0 Then
NavigateCodeElements(m_objDTE2.Solution.Projects.Item(1).CodeModel.CodeElements)
objEvents2 = DirectCast(m_objDTE2.Events, EnvDTE80.Events2)
m_objCodeModelEvents = objEvents2.CodeModelEvents
End If
End Select
End Sub
Private Sub NavigateCodeElements(ByVal colCodeElements As CodeElements)
For Each objCodeElement As CodeElement In colCodeElements
If TypeOf objCodeElement Is CodeNamespace Then
NavigateCodeElements(CType(objCodeElement, CodeNamespace).Members)
ElseIf TypeOf objCodeElement Is CodeType Then
NavigateCodeElements(CType(objCodeElement, CodeType).Members)
End If
Next
End Sub
Private Sub m_objCodeModelEvents_ElementAdded(ByVal Element As EnvDTE.CodeElement) Handles m_objCodeModelEvents.ElementAdded
MessageBox.Show(Element.Name & " added")
End Sub
Private Sub m_objCodeModelEvents_ElementChanged(ByVal Element As EnvDTE.CodeElement, ByVal Change As EnvDTE80.vsCMChangeKind) _
Handles m_objCodeModelEvents.ElementChanged
MessageBox.Show(Element.Name & " changed: " & Change.ToString)
End Sub
Private Sub m_objCodeModelEvents_ElementDeleted(ByVal Parent As Object, ByVal Element As EnvDTE.CodeElement) _
Handles m_objCodeModelEvents.ElementDeleted
MessageBox.Show(Element.Name & " removed")
End Sub
Public Sub OnAddInsUpdate(ByRef custom As System.Array) Implements Extensibility.IDTExtensibility2.OnAddInsUpdate
End Sub
Public Sub OnBeginShutdown(ByRef custom As System.Array) Implements Extensibility.IDTExtensibility2.OnBeginShutdown
End Sub
Public Sub OnDisconnection(ByVal RemoveMode As Extensibility.ext_DisconnectMode, ByRef custom As System.Array) _
Implements Extensibility.IDTExtensibility2.OnDisconnection
End Sub
Public Sub OnStartupComplete(ByRef custom As System.Array) Implements Extensibility.IDTExtensibility2.OnStartupComplete
End Sub
End Class
Go back to the 'Resources for Visual Studio .NET extensibility' section for more articles like this
|