Subscribing to an Event
This walkthrough explains how to create a tool window that responds to events in a running document table (RDT). A tool window hosts a user control that implements IVsRunningDocTableEvents. The AdviseRunningDocTableEvents method connects the interface to the events.
Subscribing to RDT Events
To create an extension with a tool window
Create a project named RDTExplorer using the VSIX template, and add a custom tool window item template named RDTExplorerWindow.
For more information about creating an extension with a tool window, see Creating an Extension with a Tool Window.
To subscribe to RDT events
Open the RDTExplorerWindowControl.xaml file and delete the button named
button1
. Add a ListBox control and accept the default name. The Grid element should look like this:<Grid> <StackPanel Orientation="Vertical" Margin="-10,10,10,0"> <TextBlock Margin="10" HorizontalAlignment="Center">RDTExplorerWindow</TextBlock> <ListBox x:Name="listBox" Height="100" /> </StackPanel> </Grid>
Open the RDTExplorerWindow.cs file in code view. Add the following using directives to the start of the file.
using Microsoft.VisualStudio; using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Shell.Interop;
Modify the
RDTExplorerWindow
class so that, in addition to deriving from the ToolWindowPane class, it implements the IVsRunningDocTableEvents interface.public class RDTExplorerWindow : ToolWindowPane, IVsRunningDocTableEvents {. . .}
Implement IVsRunningDocTableEvents.
- Implement the interface. Place the cursor on the IVsRunningDocTableEvents name. You should see a light bulb in the left margin. Click the Down arrow to the right of the light bulb and select Implement interface.
In each method in the interface, replace the line
throw new NotImplementedException();
with this:return VSConstants.S_OK;
Add a cookie field to the RDTExplorerWindow class.
private uint rdtCookie;
This holds the cookie that is returned by the AdviseRunningDocTableEvents method.
Override the RDTExplorerWindow's Initialize() method to register for RDT events. You should always get services in the ToolWindowPane's Initialize() method, not in the constructor.
protected override void Initialize() { IVsRunningDocumentTable rdt = (IVsRunningDocumentTable) this.GetService(typeof(SVsRunningDocumentTable)); rdt.AdviseRunningDocTableEvents(this, out rdtCookie); }
The SVsRunningDocumentTable service is called to obtain an IVsRunningDocumentTable interface. The AdviseRunningDocTableEvents method connects RDT events to an object that implements IVsRunningDocTableEvents, in this case, a RDTExplorer object.
Update the RDTExplorerWindow's Dispose() method.
protected override void Dispose(bool disposing) { // Release the RDT cookie. IVsRunningDocumentTable rdt = (IVsRunningDocumentTable) Package.GetGlobalService(typeof(SVsRunningDocumentTable)); rdt.UnadviseRunningDocTableEvents(rdtCookie); base.Dispose(disposing); }
The UnadviseRunningDocTableEvents method deletes the connection between
RDTExplorer
and RDT event notification.Add the following line to the body of the OnBeforeLastDocumentUnlock handler, just before the
return
statement.public int OnBeforeLastDocumentUnlock(uint docCookie, uint dwRDTLockType, uint dwReadLocksRemaining, uint dwEditLocksRemaining) { ((RDTExplorerWindowControl)this.Content).listBox.Items.Add("Entering OnBeforeLastDocumentUnlock"); return VSConstants.S_OK; }
Add a similar line to the body of the OnAfterFirstDocumentLock handler and to other events that you want to see in the list box.
public int OnAfterFirstDocumentLock(uint docCookie, uint dwRDTLockType, uint dwReadLocksRemaining, uint dwEditLocksRemaining) { ((RDTExplorerWindowControl)this.Content).listBox.Items.Add("Entering OnAfterFirstDocumentLock"); return VSConstants.S_OK; }
Build the project and start debugging. The Visual Studio experimental instance appears.
Open the RDTExplorerWindow (View / Other Windows / RDTExplorerWindow).
The RDTExplorerWindow window opens with an empty event list.
Open or create a solution.
As
OnBeforeLastDocument
andOnAfterFirstDocument
events are fired, notification of each event appears in the event list.