Search code examples
visual-studiovsixvisual-studio-extensions

Is there any extension point to manipulate Visual Studio Navigation Bar?


This is the goal: to remove Navigation Bar in some of the editors (no all of them as it is possible in Options) by an extension.

So here is it the thing that I want to remove: Navigation bar

I have checked many ways, the most promising one was to access it in an IWpfTextViewMargin after the load:

IWpfTextViewHost TextViewHost;
IWpfTextViewMargin ContainerMargin;

public DummyMargin(IWpfTextViewHost textViewHost, 
                   IWpfTextViewMargin containerMargin)
{
    this.TextViewHost = textViewHost;
    this.ContainerMargin = containerMargin;
    Loaded += DummyMargin_Loaded;

}

void DummyMargin_Loaded(object sender, System.Windows.RoutedEventArgs e)
{
    // ContainerMargin is loaded here
}

And then traverse upward in visual tree to find the navigation bar and hide it there:

Virtual Tree

But this is a very dirty and unreliable solution. Do you know any better one? especially if there is an extension point (like one of these: Editor Extension Points) for manipulating it.


Solution

  • So the API that the language services use to manipulate the contents of the drop down bars is IVsDropdownBarManager. If you called RemoveDropdownBar at an appropriate time and the drop down bar would be removed and you don't have to go playing with the WPF visual tree.

    There are a few problems with this approach:

    1. "an appropriate time" is not well defined, and each language service may initialize it's drop down bar at a different time. Most language services will do it during the AddAdorments phase of their IVsCodeWindow, but that's not something you can hook into.

    2. You need to get the IVsCodeWindow for a given window, which itself is tricky and not necessarily reliable. I'd point you to Jared Parson's VsVim code which shows how to do it. If you look in this file you can get an IVsTextView, then call GetWindowFrame to get the IVsWindowFrame for it. Once you have that, then call GetCodeWindow to get the IVsCodeWindow. Then cast that to IVsDropdownBarManager and start playing around.

    3. This is still very slimy as you're doing things behind the language service's back which it may not anticipate. I wouldn't be surprised if various language services would crash if you were doing this to them.

    That said, if your goal here is to make a simple extension for your self because you don't like the nav bars or want to try something else, you should be able to get this to work. But it's sure not a supported/nice way of doing it.