Twenty
Twenty

Reputation: 5911

Only show command in context menu on specific filename (+extension)

So basically I only want to display the Command when I right click on a file named "example.cs". Since I am using Visual Studio 2019 I can't go with the old BeforeQueryStatus way. Instead using the ProvideUIContextRule Attribute on my Package class. Which currently looks something like this:

    [ProvideUIContextRule(_uiContextSupportedFiles,
    name: "Supported Files",
    expression: "CSharp",
    termNames: new[] { "CSharp" },
    termValues: new[] { "HierSingleSelectionName:.cs$" })]

Which totally looks fine for the extension of the file itself. So is there any way to restrict it to example.cs?

By the way I am using this Guide.

Upvotes: 5

Views: 1055

Answers (2)

Twenty
Twenty

Reputation: 5911

So for everyone else having the same issue as I had. The solution is fairly simple, regarding to the MSDN:

(...) The term evaluates to true whenever the current selection in the active hierarchy has a name that matches the regular expression pattern(...)

So basically changing { "HierSingleSelectionName:.cs$" } to { "HierSingleSelectionName:Program.cs$" } will only show files that end with Program.cs.

This leads to, that everything after the semicolon contains a Regular Expression.

Upvotes: 2

vik_78
vik_78

Reputation: 1157

To determine your command's visibility, you can implement QueryStatus method.

Implement Microsoft.VisualStudio.OLE.Interop.IOleCommandTarget like CommandsFilter. And add it as service to package.

var serviceContainer = (IServiceContainer)this; // this - is your Package/AsyncPakage
var commandTargetType = typeof(IOleCommandTarget);
var commandsFilter = new CommandsFilter();
serviceContainer.RemoveService(commandTargetType);
serviceContainer.AddService(commandTargetType, commandsFilter);

On every commands update will be called method QueryStatus in CommandsFilter. Wait for your command id and change it status

class CommandsFilter : IOleCommandTarget {
// ...
public int QueryStatus(ref Guid pguidCmdGroup, uint cCmds, OLECMD[] prgCmds, IntPtr pCmdText) {
    var cmdId = prgCmds[0].cmdID;
    // check cmdId and set status depends on your conditions
    // like fileName == "example.cs"
    prgCmds[0].cmdf = (uint)GetVsStatus(status);

    //....
}

private OLECMDF GetVsStatus(CommandStatus commandStatus) {

  OLECMDF ret = 0;
  if (commandStatus.HasFlag(CommandStatus.Supported))
    ret |= OLECMDF.OLECMDF_SUPPORTED;
  if (commandStatus.HasFlag(CommandStatus.Enabled))
    ret |= OLECMDF.OLECMDF_ENABLED;
  if (commandStatus.HasFlag(CommandStatus.Invisible))
    ret |= OLECMDF.OLECMDF_INVISIBLE;
  return ret;
}

Check sample with QueryStatus and others MS samples

Upvotes: 0

Related Questions