For the sake of completeness, I have added another sample to the list of samples about creating top menus, submenus, toolbars, etc. that I created a few days ago on GitHub:
HOWTO: Create a Visual Studio context menu
Demonstrates how to create a context menu that is shown when right-clicking on a toolwindow. To show the toolwindow click the View > Other Windows > My toolwindow command.
That is, in this case we don’t want to add a menu entry to an existing context menu, but we want to create a whole context menu with entries to be shown when right-clicking on something, typically a control of a modal dialog or a toolwindow that belongs to our package.
There are a couple of ways to accomplish this:
The first one is using automation (EnvDTE): you create by code a commandbar that you show using the CommandBar.ShowPopup method. This was the only approach for add-ins and you have a sample in the article HOWTO: Create a context menu using a Visual Studio commandbar popup from an add-in. Since packages can use DTE, this approach is suitable. The commandbar can even have menu entries without an underlying command. But this approach is not the focus of this post.
The second one, only for packages, is using a .vsct file. The Menu element of the .vsct file can be of several kinds, and one of them is “Context”. Then you add commands to it through a group, like any other type of menu. But how is shown?. You need to use either the IOleComponentUIManager.ShowContextMenu method or the IVsUIShell.ShowContextMenu method. I have used the latter method, which receives several parameters such as the Guid of the command set, the Id of the context menu (both defined in the .vsct file) and the point where to show it.
The sample also shows the correct approach to initialize the usercontrol of a toolwindow (to pass it the package). Take into account that a toolwindow in Visual Studio can be shown in two cases:
- Clicking the command that shows the toolwindow.
- Automatically when Visual Studio is launched if the toolwindow was shown when Visual Studio was closed the last time. Visual Studio is smart enough to know the package owner of the toolwindow to show, then it loads the package and shows the toolwindow.
The initialization of the usercontrol cannot be done in the constructor of the toolwindow when the usercontrol is created because at that point the base.Package is null in the case 2:
public MyToolWindow() : base(null) { this.Caption = "My toolwindow"; m_toolWindowControl = new ToolWindowControl(); this.Content = m_toolWindowControl; }
Instead, you need to override the OnToolWindowCreated method since at this point the base.Package is already initialized:
public override void OnToolWindowCreated() { VSPackageContextMenu package; base.OnToolWindowCreated(); package = (VSPackageContextMenu)base.Package; m_toolWindowControl.Initialize(package); }