Visual Studio扩展:UI上下文规则未生效

编程语言 2026-07-10

我正在开发一个Visual Studio扩展,基本上是一个用来帮助执行我们需要定期进行的某些JSON文件操作的工具。为此,我的目标是在解决方案资源管理器中创建一个只有在右键点击JSON文件时才显示的上下文菜单项。我已经让命令工作起来,但它在所有文件上都显示。我甚至尝试使用微软网站上针对仅 .config.cs 文件的示例,但即使那样也没起作用;命令仍然会在资源管理器中的每个项上显示。

使用微软针对 .config 文件的示例,我的包被定义为:

[PackageRegistration(UseManagedResourcesOnly = true, AllowsBackgroundLoading = true)]
[Guid(QuickSwapSettingsExtensionPackage.PackageGuidString)]
[ProvideMenuResource("Menus.ctmenu", 1)]
[ProvideAutoLoad(UIContextGuid, PackageAutoLoadFlags.BackgroundLoad)]
[ProvideUIContextRule(UIContextGuid,
    name: "Apply only to JSON files",
    expression: "DotConfig",
    termNames: new[] { "DotConfig" },
    termValues: new[] { "HierSingleSelectionName:.config$" })]
public sealed class QuickSwapSettingsExtensionPackage : AsyncPackage
{
    /// <summary>
    /// QuickSwapSettingsExtensionPackage GUID string.
    /// </summary>
    public const string PackageGuidString = "d6069cfa-a050-490c-bf8a-5ddb780e204d";

    public const string UIContextGuid = "2cfcc18c-f6b5-418a-8531-2b8f3bf53cf5";

    ...
}

在VSCT文件中,我的按钮被定义为:

<Commands package="guidQuickSwapSettingsExtensionPackage">
    <Groups>
        <Group guid="guidQuickSwapSettingsExtensionPackageCmdSet" id="MyMenuGroup" priority="0x0600">
            <Parent guid="guidSHLMainMenu" id="IDM_VS_CTXT_ITEMNODE"/>
        </Group>
    </Groups>

    <Buttons>
        <Button guid="guidQuickSwapSettingsExtensionPackageCmdSet" id="SwapSettingsCommandId" priority="0x0100" type="Button">
            <Parent guid="guidQuickSwapSettingsExtensionPackageCmdSet" id="MyMenuGroup" />
            <Icon guid="guidImages" id="bmpPic1" />
            <CommandFlag>DynamicVisibility</CommandFlag>
            <Strings>
                <ButtonText>Invoke SwapSettingsCommand</ButtonText>
            </Strings>
        </Button>
    </Buttons>
    <Bitmaps>
        <Bitmap guid="guidImages" href="Resources\SwapSettingsCommand.png" usedList="bmpPic1, bmpPic2, bmpPicSearch, bmpPicX, bmpPicArrows, bmpPicStrikethrough"/>
    </Bitmaps>
</Commands>

我还添加了用于可见性约束的部分:

<VisibilityConstraints>
    <VisibilityItem guid="guidQuickSwapSettingsExtensionPackageCmdSet" id="SwapSettingsCommandId" context="UIContextGuid"/>
</VisibilityConstraints>

以及添加了GUID符号:

<Symbols>
    <!-- This is the package guid. -->
    <GuidSymbol name="guidQuickSwapSettingsExtensionPackage" value="{d6069cfa-a050-490c-bf8a-5ddb780e204d}" />

    <GuidSymbol name="UIContextGuid" value="{2cfcc18c-f6b5-418a-8531-2b8f3bf53cf5}" />
</Symbols>

据我的理解,按照这个设置,当我对扩展名为 .config 的文件右键点击时,菜单项命令应该才会显示。然而,当扩展加载时,如果我对一个非配置文件右键,菜单项不会出现。等我对一个 .config 文件右键时,新的菜单项就会出现,但随后它会对所有其他文件也显示,无论扩展名是什么。

似乎菜单项在我点击 .config 文件后就被添加,并且永久存在,在点击其他文件时不会移除。我到底遗漏了什么?我希望上下文菜单项仅在所选项是JSON项时显示(如果更容易实现,也可以显示出来,但对其他文件类型禁用)。

解决方案

我终于找到了一个解决办法,希望对遇到同样情况的其他人有所帮助。

最初,在我的命令中,我是用以下方式创建菜单项:

var menuItem = new MenuCommand(Execute, menuCommandId);

我把它修改为:

var menuItem = new OleMenuCommand(Execute, menuCommandId)
{
    Supported = false
};

通过将类型定义为一个 OleMenuCommand,而不仅仅是一个 MenuCommand,并将 Supported 设置为 false,现在菜单项只会显示在我想要的文件上(即本例中的JSON文件)。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章