仅在特定文件名(+扩展名)的上下文菜单中显示命令
Only show command in context menu on specific filename (+extension)
所以基本上我只想在右键单击名为 "example.cs" 的文件时显示命令。由于我使用的是 Visual Studio 2019,所以我不能使用旧的 BeforeQueryStatus
方式。而是在我的包 class 上使用 ProvideUIContextRule
属性。目前看起来像这样:
[ProvideUIContextRule(_uiContextSupportedFiles,
name: "Supported Files",
expression: "CSharp",
termNames: new[] { "CSharp" },
termValues: new[] { "HierSingleSelectionName:.cs$" })]
这对于文件本身的扩展名来说完全没问题。那么有没有办法限制到example.cs
?
顺便说一句,我正在使用这个 Guide。
要确定命令的可见性,您可以实现 QueryStatus 方法。
像 CommandsFilter 一样实现 Microsoft.VisualStudio.OLE.Interop.IOleCommandTarget
。并将其作为服务添加到包中。
var serviceContainer = (IServiceContainer)this; // this - is your Package/AsyncPakage
var commandTargetType = typeof(IOleCommandTarget);
var commandsFilter = new CommandsFilter();
serviceContainer.RemoveService(commandTargetType);
serviceContainer.AddService(commandTargetType, commandsFilter);
每次更新命令时,都会调用 CommandsFilter 中的方法 QueryStatus
。
等待您的命令 ID 并更改它的状态
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;
}
用 QueryStatus
和其他 MS 样本检查 sample
对于和我有同样问题的其他人来说。解决方法很简单,参考MSDN:
(...) The term evaluates to true whenever the current selection in the active hierarchy has a name that matches the regular expression pattern(...)
所以基本上改变了
{ "HierSingleSelectionName:.cs$" }
到 { "HierSingleSelectionName:Program.cs$" }
将只显示以 Program.cs
结尾的文件。
这导致分号后的所有内容都包含正则表达式。
所以基本上我只想在右键单击名为 "example.cs" 的文件时显示命令。由于我使用的是 Visual Studio 2019,所以我不能使用旧的 BeforeQueryStatus
方式。而是在我的包 class 上使用 ProvideUIContextRule
属性。目前看起来像这样:
[ProvideUIContextRule(_uiContextSupportedFiles,
name: "Supported Files",
expression: "CSharp",
termNames: new[] { "CSharp" },
termValues: new[] { "HierSingleSelectionName:.cs$" })]
这对于文件本身的扩展名来说完全没问题。那么有没有办法限制到example.cs
?
顺便说一句,我正在使用这个 Guide。
要确定命令的可见性,您可以实现 QueryStatus 方法。
像 CommandsFilter 一样实现 Microsoft.VisualStudio.OLE.Interop.IOleCommandTarget
。并将其作为服务添加到包中。
var serviceContainer = (IServiceContainer)this; // this - is your Package/AsyncPakage
var commandTargetType = typeof(IOleCommandTarget);
var commandsFilter = new CommandsFilter();
serviceContainer.RemoveService(commandTargetType);
serviceContainer.AddService(commandTargetType, commandsFilter);
每次更新命令时,都会调用 CommandsFilter 中的方法 QueryStatus
。
等待您的命令 ID 并更改它的状态
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;
}
用 QueryStatus
和其他 MS 样本检查 sample
对于和我有同样问题的其他人来说。解决方法很简单,参考MSDN:
(...) The term evaluates to true whenever the current selection in the active hierarchy has a name that matches the regular expression pattern(...)
所以基本上改变了
{ "HierSingleSelectionName:.cs$" }
到 { "HierSingleSelectionName:Program.cs$" }
将只显示以 Program.cs
结尾的文件。
这导致分号后的所有内容都包含正则表达式。