添加 Visual Studio 命令

类表示 Command 的命令是一些可由用户启动的操作,例如当用户选择菜单项、按工具栏按钮或键入键盘快捷方式时。 命令具有显示名称、执行方法(ExecuteCommandAsync)来执行操作、工具栏中显示的图标以标识命令,以及向用户解释命令的工具提示。 可以根据各种条件启用或禁用命令。

新的扩展性模型中的命令以异步方式运行,以便用户可以在执行命令时继续与 IDE 交互。

使用命令

本概述介绍用于处理命令的这些主要方案:

创建命令

使用新的扩展性模型创建命令首先扩展基类 Command,使用 VisualStudioContribution 特性装饰类并实现 CommandConfiguration 属性。

[VisualStudioContribution]
public class MyCommand : Command
{
  /// <inheritdoc />
  public override CommandConfiguration CommandConfiguration => new("%MyCommand.DisplayName%");
}

CommandConfiguration 类

CommandConfiguration 类具有一些应该熟悉的参数:

参数 类型​​ 必需 说明
DisplayName String 命令的默认显示名称。 将此字符串与“%”字符括起来,以启用此字符串的本地化。 请参阅本地化 元数据
ToolTipText 字符串 当命令悬停或聚焦时要显示为工具提示的文本。 将此字符串与“%”字符括起来,以启用此字符串的本地化。 请参阅本地化 元数据
标记 CommandFlags 用于在命令上设置其他属性的标志。 某些选项包括 CanToggle 和 CanSelect。 请参阅命令标志
放置 CommandPlacement[] 指定命令将父级到 Visual Studio 中的现有组。 请参阅在 IDE 中放置命令。 即使没有放置,命令仍可通过 Visual Studio 搜索功能获得。 还可以将命令放置在 扩展中定义的菜单、工具栏和组 上。
图标 CommandIconConfiguration 命令可以在 UI 中显示为“图标”、“带文本的图标”或“仅文本”。 此属性配置图标应是什么(如果有),以及应如何显示它。
快捷方式 CommandShortcutConfiguration[] 定义可用于执行命令的键组合集。 快捷方式的范围可以缩小到仅适用于特定的 IDE 上下文。 请参阅快捷方式
ClientContexts[] 字符串 命令请求的客户端上下文。 默认情况下,返回 Shell 和编辑器上下文。 客户端上下文是最初执行命令时特定 IDE 状态的快照。 由于这些命令以异步方式执行,因此此状态可能会在用户执行命令和命令处理程序运行时发生更改。 请参阅客户端上下文

示例

还需要 Command 一个构造函数,该构造函数采用 VisualStudioExtensibility 对象(允许与 IDE 通信),以及执行方法 ExecuteCommandAsync。 以下示例提供不执行任何操作的泛型命令的最小实现:

[VisualStudioContribution]
public class MyCommand : Command
{
    /// <inheritdoc />
    public override CommandConfiguration CommandConfiguration => new("%MyCommand.DisplayName%");

    public MyCommand(VisualStudioExtensibility extensibility)
        : base(extensibility)
    {
    }

    public override Task ExecuteCommandAsync(IClientContext context, CancellationToken cancellationToken)
    {
        return Task.CompletedTask;
    }
}

在 IDE 中放置命令

Visual Studio 中有一组定义完善的位置,可在其中放置命令。 这些位置由类CommandPlacement上的属性KnownPlacements定义。 当前集 KnownPlacements 为:

  • ToolsMenu - 该命令将放置在 Visual Studio 的顶级“工具”菜单下的组中。
  • ViewOtherWindowsMenu - 该命令将放置在 Visual Studio 的顶级“视图”-> “其他 Windows”菜单下的组中。
  • ExtensionsMenu - 该命令将放置在 Visual Studio 的顶级“扩展”菜单下的组中。

通过指定Guid通过 VSCT 定义的组,Id还可以使用CommandPlacement.VsctParent该方法放置命令。

对同一组的父级命令根据其位置 Priority 的属性进行排序,相对于具有相同放置的其他命令或菜单。 Priority默认值为CommandPlacement0/>,可以通过调用CommandPlacement.WithPriority方法来修改,并传入所需的Priority值。

public override CommandConfiguration CommandConfiguration => new("%MyCommand.DisplayName%")
{
    // The command will be parented to a group inside of the "Tools" top level menu,
    // a group inside of the "Extensions" top level menu, and the "About" group inside of the "Help" top level menu
    Placements = new CommandPlacement[]
    {
        CommandPlacement.KnownPlacements.ToolsMenu,
        CommandPlacement.KnownPlacements.ExtensionsMenu.WithPriority(0x0100),
        CommandPlacement.VsctParent(new Guid("{d309f791-903f-11d0-9efc-00a0c911004f}"), id: 0x016B, priority: 0x0801),
    },
};

向命令添加图标

除了命令的显示名称,命令还支持将图标添加到其菜单项,或者支持将图标添加到其菜单项。 若要向命令添加图标,请在命令的属性CommandConfiguration上设置Icon属性。

CommandIconConfiguration

CommandIconConfiguration 两个参数:

参数 类型​​ 必需 说明
IconName ImageMoniker 可以为在 “添加自定义图像 ”部分添加的图像使用自定义名字对象,也可以引用 Visual Studio ImageMoniker ,例如 ImageMonikers.KnownValues.AddItem
图标设置 图标设置 配置命令的显示方式。 例如 IconSettings.IconAndText ,将图标与命令的显示名称一起显示,而 IconSettings.IconOnly 仅显示命令的图标,而不显示其 DisplayName(如果父级为工具栏)。

ImageMoniker.KnownValues 示例

public override CommandConfiguration CommandConfiguration => new("%MyCommand.DisplayName%")
{
    Icon = new CommandIconConfiguration(ImageMoniker.KnownValues.Extension, IconSettings.IconAndText),
};

使用命令图标的自定义图像

可以添加自定义映像,然后可以通过以下步骤使用自定义名字对象进行引用:

  1. 重命名图像源文件以遵循 %Custom Moniker%.* 模式(例如 MyImage.1.png)。 以同一名字对象为前缀的文件将全部用作同一自定义名字对象的后盾源。 将根据请求的图标大小使用不同的源。
    • 例如,MyImage.16.16.png(a 16*16 png)、MyImage.20.20.png(20*20 png)和 MyImage.xaml 都被视为源MyImage
    • 当请求的图标大小为 16*16 时,将使用 MyImage.16.16.png,当请求的大小为 20*20 时,将使用 MyImage.20.20.png,在所有其他情况下,将使用 MyImage.xaml
  2. 将所有图像源文件放在文件夹下 Images
    • 默认图像资产文件夹是 Images,但也可以通过添加来自定义它 <ImageAssetsPath>%YourFolder%</ImageAssetsPath>

ImageMoniker.Custom 示例

public override CommandConfiguration CommandConfiguration => new("%MyCommand.DisplayName%")
{
    Icon = new CommandIconConfiguration(ImageMoniker.Custom("MyImage"), IconSettings.IconAndText),
};

快捷方式

可以使用特定组合键时配置命令以执行。 快捷方式由一个或两个和弦组成,其中每个弦由一 ModifierKey 个和一 Key个组成。 可能的值为 ModifierKeyLeftAlt,、Shift、、 ControlShiftLeftAltControlControlShiftNone,仅None当在快捷方式的第二个和弦中使用时才有效。 ModifierKey这两个弦不需要用于快捷方式中的两个弦。 Key和弦中使用的键几乎可以是任何其他键盘键。

Visual Studio 中已使用许多键盘快捷方式。 不应将相同的快捷方式分配给多个命令,因为重复绑定难以检测,也可能导致不可预知的结果。 因此,最好在分配快捷方式之前验证快捷方式的可用性。

快捷方式激活约束

激活约束可以包含在配置中,以便在不同的上下文中提供快捷方式。 这些激活约束以编辑器 Guid的形式定义,通常与编辑器相关。 当为快捷方式提供激活约束时,它仅在该特定上下文中可用。 例如,使用 Guid “{5EFC7975-14BC-11CF-9B2B-00AA00573819}”使快捷方式在 Visual Studio 编辑器中可用。 在这种情况下,仅当将 Visual Studio 编辑器聚焦在一起时,快捷方式才可用。

快捷方式示例

public override CommandConfiguration CommandConfiguration => new("%MyCommand.DisplayName%")
{
    Shortcuts = new CommandShortcutConfiguration[]
    {
        new(ModifierKey.LeftAlt, Key.M),
        new(ModifierKey.ControlShift, Key.Y, ModifierKey.ControlShift, Key.B),
    },
};

配置命令

可以配置命令的可见性和已启用/禁用状态,并使用标志设置其他元数据。

能见度

可以通过在命令的属性上设置 VisibleWhen 属性来控制命令的 CommandConfiguration可见性。

该特性支持通过多个单个参数来指定条件,这些参数共同指定条件及其所有逻辑和输入。 若要指定条件,请在一个参数中指定表达式,定义另一个参数的表达式中使用的一组术语(字符串),并在第三个参数中的计算时将这些术语替换为哪些值。 表达式、术语和值的组合称为基于规则的激活约束,在基于规则的激活约束完全描述。

如果从配置中省略此属性,则默认为命令始终可见。

可见性示例

public override CommandConfiguration CommandConfiguration => new("My command")
{
    VisibleWhen = ActivationConstraint.ClientContext(ClientContextKey.Shell.ActiveSelectionFileName, @"\.(jpg|jpeg|txt)$"),
};

启用/禁用状态

可以通过在命令的属性上设置 EnabledWhen 属性来控制命令的 CommandConfiguration启用/禁用状态。

这种类型的配置称为基于规则的激活约束,在“使用基于规则的激活约束”中完全描述。

如果从命令中省略此配置,则默认为始终启用该命令。 如果命令当前正在执行,还可以通过在命令类的构造函数中设置 this.DisableDuringExecution = true; 来自动禁用命令。 设置此属性将替代执行命令时配置定义的 EnabledWhen 已启用/禁用状态。

Enabled/disabled 状态示例

public override CommandConfiguration CommandConfiguration => new("My command")
{
    EnabledWhen = ActivationConstraint.ClientContext(ClientContextKey.Shell.ActiveSelectionFileName, @"\.(jpg|jpeg|txt)$"),
};

有关有效术语值的详细信息,请参阅 基于规则的激活约束

命令标志

命令标志有助于在运行时使用的命令上定义其他属性,以定义命令可以具有的特殊行为。 当前支持的标志包括:

  • CanToggle - 指示 IsChecked 命令的属性可以更改,以便屏幕阅读器可以正确报出命令。 在功能上,它确保自动化属性 IsTogglePatternAvailable 为 UI 元素返回 true。
  • CanSelect - 指示 IsChecked 命令的属性可以更改,以便屏幕阅读器可以正确报出命令。 在功能上,它确保自动化属性 IsSelectionPatternAvailable 为 UI 元素返回 true。

更改命令的显示名称

虽然命令的显示名称最初在命令(请参阅“创建命令”)中CommandConfiguration设置,但在运行时可以通过在命令中设置DisplayName属性来更改它。 ToolTipText该属性可以采用类似的方式进行更新。

更改 DisplayName 示例

[VisualStudioContribution]
public class MyCommand : Command
{
    /// <inheritdoc />
    public override CommandConfiguration CommandConfiguration => new("Initial Display Name");

    public MyCommand(VisualStudioExtensibility extensibility)
     : base(extensibility)
    {
    }

    public override Task ExecuteCommandAsync(IClientContext context, CancellationToken cancellationToken)
    {
        // Update the command's Display Name
        this.DisplayName = "Updated Display Name";
        return Task.CompletedTask;
    }
}

后续步骤