Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Visual Studio Package: Settings the visibility of a custom Solution Explorer context menu item

I am creating a Visual Studio Package (this is my first time) and my end goal is to create a context-menu item for the solution explorer that only works on certain file types. (I thought this would be a common thing, but didn't find any decent tutorials on it, so if you know any please let me know)

I followed a simple MSDN guide to create an item in the toolbar first (I forget where is was to link it) and this worked fine.

Then I found a way to move it to the Solution Explorer context menu. This was achieved by manipulating the .vsct file and having an element like this:

<Parent guid="guidSHLMainMenu" id="IDM_VS_CTXT_ITEMNODE"/>

That probably doesn't matter, but I am trying to set the scene.

Now, because I want to only show the item for certain file types, I need to find a way to check the file when the right-click button is pressed. Cutting a long search short, I found this and ended up with the following code:

protected override void Initialize()
{
    //stuff
    OleMenuCommandService mcs = GetService(typeof(IMenuCommandService)) as OleMenuCommandService;
    menuItem.BeforeQueryStatus += menuItem_BeforeQueryStatus;
    //more stuff
}

void menuItem_BeforeQueryStatus(object sender, EventArgs e)
{
    var myCommand = sender as OleMenuCommand;
    myCommand.Text = "NEW NAME";
}

In the above example I am just trying to set the text to try and prove it works, I know there is a Visible property but I want this step to work first. The BeforeQueryStatus event is fired, and debugging shows the code executing as expected. However, there is no change in the context menu item, it stays with the original text.

What am I missing here? Why is it not updating?

like image 758
musefan Avatar asked Mar 21 '13 15:03

musefan


People also ask

How do I configure Solution Explorer in Visual Studio?

By default, the Solution Explorer tool window appears as a pane in the upper-right side of the Visual Studio integrated development environment (IDE). If you don't see the Solution Explorer tool window, you can open it from the Visual Studio menu bar by using View > Solution Explorer, or by pressing Ctrl+Alt+L.

How do you set Auto Hide in Solution Explorer?

AutoHide that does the trick for already docked panels. It is the same as menu:Window->Auto hide all and it autohides all panels in the same stack. Either use standard menu command Alt W A respective Alt W U or give it a shortcut of its own. Auto-hide is nice, yes.

What is Solution Explorer in Visual Studio?

Solution Explorer is a special window that enables you to manage solutions, projects, and files. It provides a complete view of the files in a project, and it enables you to add or remove files and to organize files into subfolders.

How do I change the view in Visual Studio?

It's easy to set your default layout: Arrange your windows the way you like, go to the Window menu in Visual Studio and pick Apply Window Layout > My Default. If you want you can setup several window layouts by picking Window > Save Window Layout.


1 Answers

OK, so I have finally found a solution to this problem, there are a couple of things that you need to do...

STEP 1:

We need to specify that the VSPackage should "auto-load", we do this so that the code will execute when the ContextMenu is shown, because normally the VSPackage would not initialise before the UI has been shown (i.e. the menu item has been clicked). To do this we add an attribute to the Package class, like so:

[ProvideAutoLoad("{f1536ef8-92ec-443c-9ed7-fdadf150da82}")]
public sealed class MyFirstPackage : Package

You may wonder what that GUID value is, well in this case it represents the UICONTEXT_SolutionExists constant, which means the the package will auto-load when a solution exists (so when we create a new one or load one). I got this information from here, as you might be able to tell there are a number of different VSConstants that could be used.

Here are a couple more resources that list other GUID values that can be used:

  • GUID List 1
  • GUID List 2

STEP 2:

Now that the BeforeQueryStatus code is executing at the correct place, it is still confusing as to why the code doesn't actually change anything (in my question I try to change the Text). Well, the answer is, because we need to give the package permission to do so (at least that's the way I see it as being).

To do this we must edit the .vsct file. Inside there we can find a Buttons element, inside which should be our ContextMenu Button. By default there are some comments which mention the use of the CommandFlag node - this is what we want.

In order to give permission for our package to change the Text we must add the following node:

<CommandFlag>TextChanges</CommandFlag>

Now, if we run the VSPackage it should all work as expected!

If you are looking to allow permission to change the Visibility of the menu item (which was my original aim) then you can use the following CommandFlag:

<CommandFlag>DynamicVisibility</CommandFlag>

There is a full list of command flags here, with descriptions on what they do.

like image 87
musefan Avatar answered Nov 15 '22 14:11

musefan