Tabs Studio Blog (organizing Visual Studio document tabs)

September 15, 2009

Sync add-in

Filed under: Uncategorized — Tags: — Sergey Vlasov @ 8:31 am

Occasionally, I need to find one of the currently opened documents in Solution Explorer. To fulfill this necessity and to demonstrate Tabs Studio context menu extensibility I’ve created Sync add-in.

Visual Studio has the Track Active Item in Solution Explorer option that constantly syncs Solution Explorer with the currently opened document:

Track Active Item Viusal Studio option

Track Active Item Viusal Studio option


Visual Studio also has the View.TrackActivityinSolutionExplorer command that acts as a toggle for this option. With Track Active Item in Solution Explorer option turned off you can call View.TrackActivityinSolutionExplorer command twice to locate currently opened document in Solution Explorer window (if Solution Explorer window is opened).

Alternatively, Sync add-in adds the new Sync with Solution Explorer command to tab and tab extension context menus. It allows locating any opened document (not only current) and activates Solution Explorer window if it is not opened:

Sync with Solution Explorer tab extension context menu command

Sync with Solution Explorer tab extension context menu command


Sync monitors both OpeningTabExtensionContextMenu and OpeningTabContextMenu events:

engine.OpeningTabExtensionContextMenu += OpeningTabExtensionContextMenu;
engine.OpeningTabContextMenu += OpeningTabContextMenu;

In OpeningTabExtensionContextMenu it checks that TabExtension has Document and ProjectItem associated with it (to show Sync command only for document windows), stores TabExtension for later processing (if user chooses Sync command from the menu) and places the new Sync menu item after the Open Containing Folder item:

private void OpeningTabExtensionContextMenu(object sender, 
    TabsStudioExt.OpeningTabExtensionContextMenuEventArgs e)
{
    try
    {
        if (e.TabExtension.Window.Document == null || e.TabExtension.Window.Document.ProjectItem == null)
            return;
    }
    catch (System.Exception)
    {
        return;
    }
    storedTabExtension = e.TabExtension;
    PlaceMenuItem(syncTabExtensionMenuItem, e.ContextMenu);
}

To exactly place the new menu item, Sync scans all context menu items looking for the control with the OpenContainingFolder name and inserts the new item after it:

private void PlaceMenuItem(System.Windows.Controls.MenuItem menuItem,
    System.Windows.Controls.ContextMenu menu)
{
    foreach (object item in menu.Items)
    {
        if (item is System.Windows.Controls.Control)
        {
            if ((item as System.Windows.Controls.Control).Name.Equals("OpenContainingFolder"))
            {
                menu.Items.Insert(menu.Items.IndexOf(item) + 1, menuItem);
                break;
            }
        }
    }
}

When user chooses the Sync menu command, Solution Explorer window is activated, associated project item is made visible using the ExpandView method and associated element in the Solution Explorer tree is selected:

private void SyncTabExtension(object sender, System.Windows.RoutedEventArgs e)
{
    try
    {
        EnvDTE.UIHierarchy solutionExplorer = dte.ToolWindows.SolutionExplorer;
        solutionExplorer.Parent.Activate();
        EnvDTE.ProjectItem projectItem = storedTabExtension.Window.Document.ProjectItem;
        projectItem.ExpandView();

        EnvDTE.UIHierarchyItem hierarchyItem = 
            FindHierarchyItem(solutionExplorer.UIHierarchyItems, projectItem);
        if (hierarchyItem != null)
            hierarchyItem.Select(EnvDTE.vsUISelectionType.vsUISelectionTypeSelect);
    }
    catch (System.Exception)
    {
    }
}

When Sync command is invoked for a tab, all extensions in this tab are selected in the Solution Explorer tree.

Download Sync v1.0.0 for Tabs Studio v1.6.2.

Blog at WordPress.com.