How to: Manipulate Tree Views by Using UIHierarchy
Some tool windows in Visual Studio, such as Macro Explorer and Solution Explorer, do not have explicit automation objects that you can use to manipulate their contents. These tool windows do, however, have a tree view — that is, a hierarchical, outline-style, node view — that you can programmatically access. The UIHierarchy object represents the tree views in these tool windows and enables you to iterate through them and view the contents of their nodes.
Object Name |
Description |
---|---|
UIHierarchy object |
Represents the tree view in the specified tool window. |
UIHierarchyItems collection |
Represents all nodes in the tree view. |
UIHierarchyItem object |
Represents a single node in the tree view. |
By using these objects and collections, you can:
Select (singly or multiply) and view nodes in the tree view.
Move the insertion point up or down in the tree view.
Return the value of the selected item or have it perform its default action.
Visual Studio 2005 introduced ToolWindows object (which is also returned from ToolWindows) allows easier referencing of the various tool windows in Visual Studio. For example, rather than using _applicationObject.Windows.Item(EnvDTE.Constants.vsWindowKindOutput), you can now use _applicationObject.ToolWindows.OutputWindow.
Note
The dialog boxes and menu commands you see might differ from those described in Help depending on your active settings or edition. These procedures were developed with the General Development Settings active. To change your settings, choose Import and Export Settings on the Tools menu. For more information, see Working with Settings.
Example
Although the UIHierarchy object represents the contents of nearly any tool window that has a tree view, such as Solution Explorer or Macro Explorer, the tool window itself is still a Window object. The UIHierarchyItems property returns the collection of top-level nodes in the specified tool window. In Solution Explorer, there is only a single top-level node (the solution). In Macro Explorer, there is also only one top-level node (the Macros node). Consequently, the project nodes for these particular windows are in the top-level node's collection rather than in the window's UIHierarchyItems collection.
Bearing this in mind, there are two ways to access a particular node (UIHierarchyItem) in a tree view:
By using the GetItem method to directly reference the desired node using a solution/project/item pattern.
By using UIHierarchyItems.Item.UIHierarchyItems... (a collection/item/collection pattern).
To navigate deeper into a node nesting, just keep using this pattern. For example, to go to a node subordinate to the top-level node, you would use UIHierarchy.UIHierarchyItems.Item(1).UIHierarchyItems.Item(2).
Examples of how to use both techniques to access a lower-level node are demonstrated in the examples below.
These add-in examples demonstrate how to reference and use the various members of the UIHierarchy automation model to list all of the items in Solution Explorer, and all of the macros under the Samples node of Macro Explorer.
The first example uses the GetItem method strategy of accessing the contents of the References node in Solution Explorer. The second example shows how to do the same for Macro Explorer. For more information about how to run the add-in code, see How to: Compile and Run the Automation Object Model Code Examples.
Note
The following code examples channel their output in different ways. The example for Solution Explorer sends its data to a Windows message box, while the example for Macros Explorer sends its data to the Output Window. Either way is valid and has no bearing on the usage of UIHierarchy.
Imports System.Text
Public Sub OnConnection(ByVal application As Object, ByVal _
connectMode As ext_ConnectMode, ByVal addInInst As Object, _
ByRef custom As Array) Implements IDTExtensibility2.OnConnection
_applicationObject = CType(application, DTE2)
_addInInstance = CType(addInInst, AddIn)
listSlnExpNodes(_applicationObject)
End Sub
Sub listSlnExpNodes(dte as DTE2)
' Requires reference to System.Text for StringBuilder.
Dim UIH As UIHierarchy = dte.ToolWindows.SolutionExplorer
' Set a reference to the first level nodes in Solution Explorer.
' Automation collections are one-based.
Dim UIHItem As UIHierarchyItem = _
UIH.GetItem("MyAddin1\MyAddin1\References")
Dim file As UIHierarchyItem
Dim sb As New StringBuilder
' Iterate through first level nodes.
For Each file In UIHItem.UIHierarchyItems
sb.AppendLine(file.Name)
' Iterate through second level nodes (if they exist).
Dim subitem As UIHierarchyItem
For Each subitem In file.UIHierarchyItems
sb.AppendLine(" " & subitem.Name)
Next
Next
MsgBox(sb.ToString)
End Sub
using System.Text;
public void OnConnection(object application, ext_ConnectMode _
connectMode, object addInInst, ref Array custom)
{
_applicationObject = (DTE2)application;
_addInInstance = (AddIn)addInInst;
listSlnExpNodes(_applicationObject);
}
public void listSlnExpNodes(DTE2 dte)
{
// Requires reference to System.Text for StringBuilder.
UIHierarchy UIH = dte.ToolWindows.SolutionExplorer;
// Set a reference to the first level nodes in Solution Explorer.
// Automation collections are one-based.
UIHierarchyItem UIHItem =
UIH.GetItem("MyAddin1\\MyAddin1\\References");
StringBuilder sb = new StringBuilder();
// Iterate through first level nodes.
foreach ( UIHierarchyItem file in UIHItem.UIHierarchyItems )
{
sb.AppendLine(file.Name);
// Iterate through second level nodes (if they exist).
foreach ( UIHierarchyItem subitem in file.UIHierarchyItems )
{
sb.AppendLine(" "+subitem.Name);
}
}
MessageBox.Show(sb.ToString());
}
Public Sub OnConnection(ByVal application As Object, ByVal _
connectMode As ext_ConnectMode, ByVal addInInst As Object, ByRef _
custom As Array) Implements IDTExtensibility2.OnConnection
_applicationObject = CType(application, DTE2)
_addInInstance = CType(addInInst, AddIn)
ListMacroSamples1(_applicationObject)
End Sub
Sub ListMacroSamples1(ByVal dte As DTE2)
' Reference the UIHierarchy, UIHierarchyItem, and OutputWindow
' objects.
Dim UIH As UIHierarchy = CType(dte.Windows.Item _
(Constants.vsWindowKindMacroExplorer).Object, UIHierarchy)
Dim samples As UIHierarchyItem = UIH.GetItem("Macros\Samples")
Dim OWPane As OutputWindowPane = GetOutputWindowPane _
("List Macros", True)
Dim file As UIHierarchyItem
OWPane.Clear()
For Each file In samples.UIHierarchyItems
OWPane.OutputString(file.Name & _
Microsoft.VisualBasic.Constants.vbCrLf)
Dim macro As UIHierarchyItem
For Each macro In file.UIHierarchyItems
OWPane.OutputString(" " & macro.Name & _
Microsoft.VisualBasic.Constants.vbCrLf)
Next
Next
End Sub
Function GetOutputWindowPane(ByVal Name As String, Optional ByVal _
show As Boolean = True) As OutputWindowPane
' This is a support function for ListMacroSamples(). It provides
' the Output window to list the contents of the Sample node.
Dim win As Window = _applicationObject.Windows.Item _
(EnvDTE.Constants.vsWindowKindOutput)
If show Then win.Visible = True
Dim OW As OutputWindow = _applicationObject. _
ToolWindows.OutputWindow
Dim OWPane As OutputWindowPane
Try
OWPane = OW.OutputWindowPanes.Item(Name)
Catch e As System.Exception
OWPane = OW.OutputWindowPanes.Add(Name)
End Try
OWPane.Activate()
Return OWPane
End Function
public void OnConnection(object application, ext_ConnectMode
connectMode, object addInInst, ref Array custom)
{
_applicationObject = (DTE2)application;
_addInInstance = (AddIn)addInInst;
ListMacroSamples1(_applicationObject);
}
public void ListMacroSamples1(DTE2 dte)
{
// Reference the UIHierarchy, UIHierarchyItem, and OutputWindow
// objects.
UIHierarchy UIH = (UIHierarchy)
dte.Windows.Item(Constants.vsWindowKindMacroExplorer).Object;
UIHierarchyItem samples = UIH.GetItem("Macros\\Samples");
OutputWindowPane OWPane = GetOutputWindowPane("List Macros", true);
OWPane.Clear();
foreach ( UIHierarchyItem fid in samples.UIHierarchyItems )
{
OWPane.OutputString(fid.Name+Environment.NewLine);
foreach ( UIHierarchyItem macro in fid.UIHierarchyItems )
{
OWPane.OutputString(" " + macro.Name +
Environment.NewLine);
}
}
}
public OutputWindowPane GetOutputWindowPane(string Name, bool show)
{
// This is a support function for ListMacroSamples(). It provides
// the Output window to list the contents of the Sample node.
Window win = _applicationObject.Windows.Item
(EnvDTE.Constants.vsWindowKindOutput);
if (show) { win.Visible = true; }
OutputWindow OW = _applicationObject.ToolWindows.OutputWindow;
OutputWindowPane OWPane;
try
{
OWPane = OW.OutputWindowPanes.Item(Name);
}
catch (System.Exception e)
{
OWPane = OW.OutputWindowPanes.Add(Name +
Environment.NewLine + e.Message);
}
OWPane.Activate();
return OWPane;
}
This example uses the UIHierarchyItems.Item.UIHierarchyItems pattern for accessing a node in a UIHierarchy. This example lists the macros contained within the second UIHierarchy node of Macro Explorer. Note that this example also calls on the function, GetOutputWindowPane, from the example above.
Public Sub OnConnection(ByVal application As Object, ByVal _
connectMode As ext_ConnectMode, ByVal addInInst As Object, _
ByRef custom As Array) Implements IDTExtensibility2.OnConnection
_applicationObject = CType(application, DTE2)
_addInInstance = CType(addInInst, AddIn)
ListMacroSamples2(_applicationObject)
End Sub
Sub ListMacroSamples2(ByVal dte As DTE2)
Dim uih As UIHierarchy = CType(dte.Windows.Item _
(Constants.vsWindowKindMacroExplorer).Object, UIHierarchy)
' Set a reference to the second node in Macro Explorer. The
' collections are one-based.
Dim uihItem As UIHierarchyItem = _
uih.UIHierarchyItems.Item(1).UIHierarchyItems.Item(2)
Dim file As UIHierarchyItem
Dim owPane As OutputWindowPane = GetOutputWindowPane("List Macros")
For Each file In uihItem.UIHierarchyItems
owPane.OutputString(file.Name & _
Microsoft.VisualBasic.Constants.vbCrLf)
Dim macro As UIHierarchyItem
For Each macro In file.UIHierarchyItems
owPane.OutputString(" " & macro.Name & _
Microsoft.VisualBasic.Constants.vbCrLf)
Next
Next
End Sub
Function GetOutputWindowPane(ByVal Name As String, Optional ByVal _
show As Boolean = True) As OutputWindowPane
' This is a support function for ListMacroSamples(). It provides
' the Output window to list the contents of the Sample node.
Dim win As Window = _applicationObject.Windows.Item _
(EnvDTE.Constants.vsWindowKindOutput)
If show Then win.Visible = True
Dim OW As OutputWindow = _
_applicationObject.ToolWindows.OutputWindow
Dim OWPane As OutputWindowPane
Try
OWPane = OW.OutputWindowPanes.Item(Name)
Catch e As System.Exception
OWPane = OW.OutputWindowPanes.Add(Name)
End Try
OWPane.Activate()
Return OWPane
End Function
public void OnConnection(object application, ext_ConnectMode
connectMode, object addInInst, ref Array custom)
{
_applicationObject = (DTE2)application;
_addInInstance = (AddIn)addInInst;
ListMacroSamples2(_applicationObject);
}
public void ListMacroSamples2(DTE2 dte)
{
UIHierarchy uih = (UIHierarchy)
dte.Windows.Item(Constants.vsWindowKindMacroExplorer).Object;
// Set a reference to the second node in Macro Explorer. The
// collections are one-based.
UIHierarchyItem uihItem =
uih.UIHierarchyItems.Item(1).UIHierarchyItems.Item(2);
OutputWindowPane owPane = GetOutputWindowPane("List Macros", true);
foreach ( UIHierarchyItem fid in uihItem.UIHierarchyItems )
{
owPane.OutputString(fid.Name+Environment.NewLine);
foreach ( UIHierarchyItem macro in fid.UIHierarchyItems )
{
owPane.OutputString(" " + macro.Name +
Environment.NewLine);
}
}
}
public OutputWindowPane GetOutputWindowPane(string Name, bool show)
{
// This is a support function for ListMacroSamples(). It provides
// the Output window to list the contents of the Sample node.
Window win = _applicationObject.Windows.Item
(EnvDTE.Constants.vsWindowKindOutput);
if (show) { win.Visible = true; }
OutputWindow OW = _applicationObject.ToolWindows.OutputWindow;
OutputWindowPane OWPane;
try
{
OWPane = OW.OutputWindowPanes.Item(Name);
}
catch (System.Exception e)
{
OWPane = OW.OutputWindowPanes.Add(Name + Environment.NewLine +
e.Message);
}
OWPane.Activate();
return OWPane;
}
The following macro example illustrates how to use UIHierarchy to list the contents of the tree view of the Solution Explorer window.
Sub cvTreeView()
Dim uih As UIHierarchy = DTE.ToolWindows.SolutionExplorer
Dim uihItem As UIHierarchyItem
Dim uihItems As UIHierarchyItems = uih.UIHierarchyItems
Dim msg As String
For Each uihItem In uihItems
msg += uihItem.Name & vbCr
Next
MsgBox(msg)
End Sub
See Also
Tasks
How to: Control Solution Explorer
How to: Change Window Characteristics