| < Free Open Study > |
|
There is a very complex methodology for doing this. You must create a "Listener" class. The Listener must implement the IComponentChangeService interface. The following listing shows the code for a sample Listener class. You will notice that the code to associate all event handlers except ComponentAdded has been commented out. I did this because I am only interested in knowing when a component has been added.
Note | The code in this topic is provided only in the book, for example purposes. No downloadable code is provided for the appendix examples. I have tested the code in this topic in an add-in and it works. |
Imports System.ComponentModel.Design Imports System.ComponentModel.Component Imports System.ComponentModel Imports System.Windows.Forms Imports Microsoft.Office.Core Imports EnvDTE Imports Extensibility " To set up a listener, first dim a fdHost in the connect " class. Next, instance the Listener Class. Put a public " variable of IDesignerHost (fdHost) in it. " When a windowActivated event fires, check the document " caption for .vb*|.cs* [Design], indicating that we have a " Windows form designer window activated. If so, set the " fdHost object variable to the new window, and set the " fdHost variable in the Listener class. " " This will set the listener events so that when a component " is added to the designer, we will be notified. The " ComponentChangedEventArgs parameter will have the component " that is being added. " " Pass the componenet and the designerhost to the property " prompter form. " " This should work in theory; let's see how it works in " practice. " Public Class CDesignerListener Public FDHost As IDesignerHost Private m_changeService As IComponentChangeService Friend oVB As DTE ' Object constructor Public Sub Activate() 'ByVal host As IDesignerHost) ' m_host = host If FDHost Is Nothing Then Exit Sub m_changeService = FDHost.GetService(GetType( IComponentChangeService)) If Not (m_changeService Is Nothing) Then ' Clear the old component change events to prepare ' for re-siting. 'RemoveHandler m_changeService.ComponentChanged, _ ' AddressOf OnComponentChanged 'RemoveHandler m_changeService.ComponentChanging, _ ' AddressOf OnComponentChanging RemoveHandler m_changeService.ComponentAdded, _ AddressOf OnComponentAdded 'RemoveHandler m_changeService.ComponentAdding, _ ' AddressOf OnComponentAdding 'RemoveHandler m_changeService.ComponentRemoved, _ ' AddressOf OnComponentRemoved 'RemoveHandler m_changeService.ComponentRemoving, _ ' AddressOf OnComponentRemoving 'RemoveHandler m_changeService.ComponentRename, _ ' AddressOf OnComponentRename End If ' Adds an event handler for the ComponentChanged event ' if an IComponentChangeService was obtained. If Not (m_changeService Is Nothing) Then 'AddHandler m_changeService.ComponentChanged, _ ' AddressOf OnComponentChanged 'AddHandler m_changeService.ComponentChanged, _ ' AddressOf OnComponentChanged 'AddHandler m_changeService.ComponentChanging, _ ' AddressOf OnComponentChanging AddHandler m_changeService.ComponentAdded, _ AddressOf OnComponentAdded 'AddHandler m_changeService.ComponentAdding, _ ' AddressOf OnComponentAdding 'AddHandler m_changeService.ComponentRemoved, _ ' AddressOf OnComponentRemoved 'AddHandler m_changeService.ComponentRemoving, _ ' AddressOf OnComponentRemoving 'AddHandler m_changeService.ComponentRename, _ ' AddressOf OnComponentRename End If End Sub 'New ' The IComponentChange calls this right after ' a component has been changed. Private Sub OnComponentChanged(ByVal sender As Object, _ ByVal e As ComponentChangedEventArgs) ' If the host is loading, this event was not ' caused by a user, and can be ignored. If FDHost.Loading Then Return End If ' If a transaction is in progress, ' wait for a TransactionClosed ' event which indicates when it's finished. If FDHost.InTransaction Then AddHandler FDHost.TransactionClosed, _ AddressOf OnDesignerTransactionClosed Return End If ' This is a valid UserChange event, so process it. OnUserChange("OnComponentChanged: " & _ e.Component.ToString & " Type: " & _ e.Component.GetType.ToString) End Sub 'OnComponentChanged ' This is the OnComponentChanging handler method. ' This method calls ' OnUserChange to display a message that indicates ' the name of the ' handler that made the call and the type of the ' event argument. Private Sub OnComponentChanging(ByVal sender As Object, _ ByVal ce As ComponentChangingEventArgs) OnUserChange("OnComponentChanging") End Sub 'OnComponentChanging ' This is the OnComponentAdded handler method. ' This method calls ' OnUserChange to display a message that indicates ' the name of the ' handler that made the call and the type of the ' event argument. Private Sub OnComponentAdded(ByVal sender As Object, _ ByVal ce As ComponentEventArgs) 'OnUserChange("OnComponentAdded " & ce.Component.Site.Name) System.Windows.Forms.Application.DoEvents() If Connect.gbPropertyPrompter Then Dim oFH As New CFormHandler(oVB) oFH.PromptNewComponent(FDHost, ce.Component) End If End Sub 'OnComponentAdded ' This is the OnComponentAdding handler method. ' This method calls ' OnUserChange to display a message that indicates the ' name of the ' handler that made the call and the type of ' the event argument. */ Private Sub OnComponentAdding(ByVal sender As Object, _ ByVal ce As ComponentEventArgs) OnUserChange("OnComponentAdding") End Sub 'OnComponentAdding ' This is the OnComponentRemoved handler method. ' This method calls ' OnUserChange to display a message that indicates ' the name of the ' handler that made the call and the type of ' the event argument. */ Private Sub OnComponentRemoved(ByVal sender As Object, _ ByVal ce As ComponentEventArgs) OnUserChange("OnComponentRemoved") End Sub 'OnComponentRemoved ' This is the OnComponentRemoving handler method. ' This method calls ' OnUserChange to display a message that indicates the ' name of the ' handler that made the call and the type of the ' event argument. Private Sub OnComponentRemoving(ByVal sender As Object, _ ByVal ce As ComponentEventArgs) OnUserChange("OnComponentRemoving") End Sub 'OnComponentRemoving ' This is the OnComponentRename handler method. ' This method calls ' OnUserChange to display a message that indicates the ' name of the ' handler that made the call and the type of the ' event argument. */ Private Sub OnComponentRename(ByVal sender As Object, _ ByVal ce As ComponentRenameEventArgs) OnUserChange("OnComponentRename") End Sub 'OnComponentRename ' The program began listening to the TransactionClosed ' event in OnComponentChanged(). Private Sub OnDesignerTransactionClosed(ByVal sender As Object, _ ByVal e As DesignerTransactionCloseEventArgs) ' To stop listening to transaction messages, ' remove the handler. RemoveHandler FDHost.TransactionClosed, _ AddressOf OnDesignerTransactionClosed OnUserChange("OnDesignerTransactionClosed") End Sub 'OnDesignerTransactionClosed ' Called in response to a change made by the user. Private Sub OnUserChange(ByVal s As String) MsgBox(s) End Sub 'OnUserChange End Class
Once the class is coded, it must be instantiated and supplied with an object of type IDesignerHost. That causes the Listener to monitor events taking place in the Windows Forms Designer. The way that I have implemented the Listener class is by following the steps described in the following subtopics.
The code for this is shown in the following code snippet. These variables should be declared at the module level of the Connect class:
Dim fdHost As IDesignerHost Dim oListener As New CDesignerListener()
In the WindowActivated event, check the caption of the window that was activated. If the caption ends with "[Design]", you know that a Windows Forms Designer is the active window. If that is the case, you will set the fdHost object to the ActiveWindow.Object and then set the fdHost into the Listener class. Finally, you call the Activate method of the Listener object to cause it to associate the event handlers with the new fdHost object. The code for doing so is as follows:
If oVB.ActiveWindow.Caption.EndsWith("[Design]") Then fdHost = CType(oVB.ActiveWindow.Object, IDesignerHost) If fdHost.RootComponent.Site.Name <> sFDHostName Then oListener.FDHost = fdHost oListener.Activate() End If End If
| < Free Open Study > |
|