Visual Studio のコマンドを追加する

クラスによって Command 表されるコマンドは、ユーザーがメニュー項目を選択したとき、ツール バー ボタンを押したとき、キーボード ショートカットを入力したときなど、ユーザーが開始できるアクションです。 コマンドには、表示名、アクションを実行する実行メソッド (ExecuteCommandAsync)、コマンドを識別するためのツール バーに表示するためのアイコン、およびユーザーにコマンドを説明するためのヒントがあります。 コマンドは、さまざまな条件に応じて有効または無効にすることができます。

新しい機能拡張モデルのコマンドは非同期的に実行されるため、ユーザーはコマンドの実行中に引き続き IDE と対話できます。

コマンドの操作

この概要では、コマンドを操作するための次の一般的なシナリオについて説明します。

コマンドを作成する

新しい拡張モデルを使用してコマンドを作成するには、まず基本クラスを拡張し、クラス Commandに属性を VisualStudioContribution 付け、プロパティを実装します CommandConfiguration

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

CommandConfiguration クラス

この CommandConfiguration クラスには、理解しておく必要があるいくつかのパラメーターがあります。

パラメーター タイプ Required Description
DisplayName String はい コマンドの既定の表示名。 この文字列を '%' 文字で囲み、この文字列をローカライズできるようにします。 「メタデータローカライズ」を参照してください。
ToolTipText String いいえ コマンドがホバーまたはフォーカスされたときにヒントとして表示するテキスト。 この文字列を '%' 文字で囲み、この文字列をローカライズできるようにします。 「メタデータのローカライズ」を 参照してください
フラグ CommandFlags いいえ コマンドに追加のプロパティを設定するためのフラグ。 CanToggle や CanSelect などのオプションもあります。 コマンド フラグ参照してください。
配置 CommandPlacement[] いいえ コマンドの親となる Visual Studio 内の既存のグループを指定します。 「IDEコマンドを配置する」を参照してください。 配置がなくても、コマンドは Visual Studio 検索機能を介して引き続き使用できます。 また、拡張機能で定義されているメニュー、ツール バー、グループコマンドを配置することもできます。
アイコン CommandIconConfiguration いいえ コマンドは、アイコン、テキスト付きのアイコン、またはテキストとして UI に表示できます。 このプロパティは、そのアイコンの表示方法(存在する場合)、およびアイコンの表示方法を構成します。
ショートカット CommandShortcutConfiguration[] いいえ コマンドの実行に使用できるキーの組み合わせのセットを定義します。 ショートカットのスコープは、特定の IDE コンテキストにのみ適用できます。 「ショートカット」 参照してください。
ClientContexts[] String いいえ コマンドによって要求されたクライアント コンテキスト。 既定では、シェルとエディターのコンテキストが返されます。 クライアント コンテキストは、コマンドが最初に実行されたときの特定の 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 の最上位レベルの [表示] -> [その他のウィンドウ] メニューの下のグループに配置されます。
  • ExtensionsMenu - コマンドは、Visual Studio の最上位レベルの [拡張機能] メニューの下のグループに配置されます。

VSCT を使用して定義されたグループとIdグループの指定によって、メソッドをGuid使用CommandPlacement.VsctParentしてコマンドを配置することもできます。

同じグループに親されているコマンドは、配置の Priority プロパティに基づいて並べ替えられます。配置が同じ他のコマンドまたはメニューを基準にして並べ替えられます。 a の既定値Priorityは、0メソッドを呼び出して目的Priorityの値をCommandPlacement.WithPriority渡すことで変更CommandPlacementできます。

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),
    },
};

コマンドにアイコンを追加する

コマンドでは、コマンドの表示名に加えて、または代わりにアイコンをメニュー項目に追加できます。 コマンドにアイコンを追加するには、コマンドの Icon プロパティを設定します CommandConfiguration

CommandIconConfiguration

次の CommandIconConfiguration 2 つのパラメーターがあります。

パラメーター タイプ Required 説明
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 (a 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),
};

ショートカット

特定のキーの組み合わせを使用するときに実行されるようにコマンドを構成できます。 ショートカットは1つまたは2つのコードで構成され、各コードは1と1KeyModifierKey構成されています。 可能な ModifierKey 値は LeftAltShiftControlControlShiftControlShiftLeftAltNoneNone 、ショートカットの 2 番目のコードで使用する場合にのみ有効です。 ショートカットの両方のコードに同じ ModifierKey コードを使用する必要はありません。 コードで使用されるキーボードキーは Key 、ほぼすべてのキーボードキーにすることができます。

Visual Studio では既に、多くのキーボード ショートカットが使用されています。 複数のコマンドに同じショートカットを割り当てることはできません。重複するバインドは検出が困難であり、予期しない結果が発生する可能性があるためです。 そのため、割り当てる前にショートカットの可用性を確認することをお勧めします。

ショートカットのアクティブ化の制約

アクティブ化制約を構成に含め、ショートカットをさまざまなコンテキストで使用できるようにすることができます。 これらのアクティブ化制約は、形式で Guid定義され、通常はエディターに関連します。 ショートカットにアクティブ化制約が与えられると、その特定のコンテキストでのみ使用できます。 たとえば、"{5EFC7975-14BC-11CF-9B2B-00AA00573819}" を使用 Guid して、ショートカットを 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),
    },
};

コマンドを構成する

コマンドの可視性と有効/無効状態を構成し、フラグを使用して追加のメタデータを設定できます。

視程

コマンドの可視性は、コマンドのプロパティCommandConfigurationVisibleWhen設定することで制御できます。

この属性は、条件とそのすべてのロジックと入力を一緒に指定する多数の個別パラメーターを使用して条件を指定することをサポートしています。 条件を指定するには、1 つのパラメーターで式を指定し、別のパラメーターで式で使用される用語 (文字列) のセットを定義し、3 番目のパラメーターでの評価時にこれらの用語を置き換える必要がある値を定義します。 式、用語、値の組み合わせは、ルール ベースのアクティブ化制約と呼ばれ、ルール ベースのアクティブ化制約完全に説明されています。

このプロパティを構成から省略すると、既定ではコマンドが常に表示されます。

可視性の例

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

有効/無効状態

コマンドの有効/無効状態は、コマンドのプロパティCommandConfigurationEnabledWhen設定することで制御できます。

この種類の構成はルール ベースのアクティブ化制約と呼ばれ、「ルール ベースのアクティブ化制約の使用」で完全に説明されています。

この構成をコマンドから省略すると、既定ではコマンドが常に有効になります。 コマンド クラスのコンストラクターで設定 this.DisableDuringExecution = true; することで、コマンドが現在実行されている場合は、コマンドを自動的に無効にすることもできます。 このプロパティを設定すると、コマンドの実行中に構成によって定義された EnabledWhen 有効/無効状態がオーバーライドされます。

有効/無効状態の例

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;
    }
}

次のステップ