Visual Studio Macro: Locate Item in Solution Explorer on Demand
Posted by Dan Vanderboom on March 21, 2008
[ For an updated macro that works best with VS2008 and VS2010, see the followup article. ]
By default, Visual Studio’s Solution Explorer will update its selected item based on the currently active document. This is occassionally useful when exploring unfamiliar code, but it’s annoying when it’s always on, bouncing around as you navigate through larger solutions.
Do you want to disable project item tracking?
Go to Tools—>Options, expand Projects and Solutions, select General, and then uncheck the box next to Track Active Item in Solution Explorer.
But what if you’re looking at a document, and you want to know where in Solution Explorer it’s located? Unfortunately, you would have to go back into Tools—>Options, …, turn that option back on, locate the project item, and then turn it back off again.
This is very inconvenient. What would be ideal is a button or hot key that would jump to that item in Solution Explorer just once, on demand. “Where’s the corresponding project item for this document? Find it and then don’t track after that.”
After about two hours of messing around with the VS SDK, trying to read the documentation, finding out that this particular option isn’t available for manipulation through automation, and resolving to figure out another way to do it, I finally accomplished this goal and I’m happy to share the macro that I created.
Don’t know how to create a macro?
Adding a macro is easy. First open the Macro Explorer. Press Alt-F8, or if you’ve remapped your keys, go to Tools—>Macros—>Macro Explorer. You’ll probably have a project in there called MyMacros. If not, right-click on Macros and select New Macro Project… A window pops up, and you can enter a project name. Once you have selected or created a macro project, right click on the project name and select New module… I named mine Utilities. Right click on the module name and select Edit. You should now see a VB code editor window.
Copy the following code into the editor and press Ctrl-S to save it.
Imports System Imports EnvDTE Imports EnvDTE80 Imports EnvDTE90 Public Module Utilities Public Sub TrackProjectItem() Dim solution As Solution2 = DTE.Solution If Not solution.IsOpen OrElse DTE.ActiveDocument Is Nothing Then Return solution.FindProjectItem(DTE.ActiveDocument.FullName).ExpandView() Dim FileName As String = DTE.ActiveDocument.FullName Dim SolutionExplorerPath As String Dim items As EnvDTE.UIHierarchyItems = DTE.ToolWindows.SolutionExplorer.UIHierarchyItems Dim item As Object = FindItem(items, FileName, SolutionExplorerPath) If item Is Nothing Then MsgBox("Couldn't find the item in Solution Explorer.") Return End If DTE.Windows.Item(Constants.vsWindowKindSolutionExplorer).Activate() DTE.ActiveWindow.Object.GetItem(SolutionExplorerPath).Select(vsUISelectionType.vsUISelectionTypeSelect) End Sub Public Function FindItem(ByVal Children As UIHierarchyItems, ByVal FileName As String, ByRef SolutionExplorerPath As String) As Object For Each CurrentItem As UIHierarchyItem In Children Dim TypeName As String = Microsoft.VisualBasic.Information.TypeName(CurrentItem.Object) If TypeName = "ProjectItem" Then Dim projectitem As EnvDTE.ProjectItem = CType(CurrentItem.Object, EnvDTE.ProjectItem) Dim i As Integer = 1 While i <= projectitem.FileCount If projectitem.FileNames(i) = FileName Then SolutionExplorerPath = CurrentItem.Name Return CurrentItem End If i = i + 1 End While End If Dim ChildItem As UIHierarchyItem = FindItem(CurrentItem.UIHierarchyItems, FileName, SolutionExplorerPath) If Not ChildItem Is Nothing Then SolutionExplorerPath = CurrentItem.Name + "\" + SolutionExplorerPath Return ChildItem End If Next End Function End Module
Now let’s hook it up to a keyboard hot key to make it super fast to access. If you open Tools—>Options, expand Environment, select Keyboard, and in the text box labeled Show commands containing, type part of the macro name, such as TrackProjectItem. You’ll see your new macro in the list highlighted. In the dropdown control labeled Use new shortcut in, select Text Editor. Click on the box that says Press shortcut keys, and press a key combination. I chose Alt-T (for Track), which was available in that context to my surprise.
Try it out. Open up a few code or XML windows. Make one of those windows active and press your hot key. The item in Solution Explorer that corresponds to the current document window will activate.