方法: ショートカット メニューにコマンドを追加する

ユーザーが DSL に (DSL) 固有のタスクを実行できるようにドメイン固有言語にメニュー コマンドを追加できます。コマンドはコンテキスト () のショートカット メニューでユーザーが図上で右クリックすると表示されます。メニューでのみ特別な場合に表示されるコマンドを定義できます。たとえばユーザーが要素の種類をクリックするか特定の状態の要素を参照している場合にのみコマンド表示する。

まとめるとDslPackage の手順ではプロジェクトに次のように最後に丸め :

  1. Commands.vsct のコマンドを宣言します。

  2. Package.tt パッケージのバージョン番号を更新します。。Commands.vsct を変更するたびに行う必要があります

  3. コマンドが表示されるようにしそのコマンドを表示するを定義する クラスのメソッドを記述 CommandSet。

例についてはVisualization and Modeling SDK website" " を参照してください。

[!メモ]

または CommandSet.cs のメソッドをオーバーライドして切り取り貼り付けすべて選択し印刷など既存のコマンドの動作を変更できます。詳細については、「方法: ドメイン固有言語における標準のメニュー コマンドを修正する」を参照してください。

MEF を使用してコマンドを定義する

マネージ拡張フレームワークは (MEF)右クリックしてメニュー コマンドを定義する方法を示します。その主な目的はまたは他の人がDSL を有効にします。ユーザーはDSL をインストールするように選択できます。またはDSL および拡張子の両方をインストールできます。ただしDSL の MEF を有効にするにはMEF は最初の後にショートカット メニュー コマンドを定義する作業は短縮できます。

このトピックではメソッドを使用する :

  1. 右クリックで表示されるショートカット メニューのメニューのメニュー コマンドを定義する必要があります。

  2. メニューのコマンドの特定のグループを定義します。

  3. 独自のコマンドではDSL を拡張するための残りができるようにする必要があります。

  4. の 1 個のコマンドを定義する必要があります。

はMEF のメソッドを使用してコマンドを定義することを検討してください。詳細については、「MEF による DSL の拡張」を参照してください。

Commands.Vsct のコマンドを宣言します。

メニュー コマンドは DslPackage \ Commands.vsct で宣言されています。これらの定義はメニューに表示されるメニュー項目のラベルを指定します。

編集Commands.vsctディレクトリ Visual Studio SDK インストール パス \ VisualStudioIntegration \ Common バークリーには複数の .h ファイルの定義ファイルのインポートまたDSL 定義から生成される GeneratedVsct.vsct が含まれています。

.vsct のファイルの詳細についてはVisual Studio のコマンド (テーブル。Vsct) ファイル を参照してください。

コマンドを追加するには

  1. ソリューション エクスプローラー では***** DslPackage ***** のプロジェクトでCommands.vsct を開きます。

  2. Commands の要素には一つ以上のボタンとグループを定義します。 ボタンが メニューの項目です。 グループは メニューのセクションです。これらの項目を定義するには次の要素を追加します :

    <!-- Define a group - a section in the menu -->
    <Groups>
      <Group guid="guidCustomMenuCmdSet" id="grpidMyMenuGroup" priority="0x0100">
        <!-- These symbols are defined in GeneratedVSCT.vsct -->
        <Parent guid="guidCmdSet" id="menuidContext" />
      </Group>
    </Groups>
    <!-- Define a button - a menu item - inside the Group -->
    <Buttons>
      <Button guid="guidCustomMenuCmdSet" id="cmdidMyContextMenuCommand"
        priority="0x0100" type="Button">
        <Parent guid="guidCustomMenuCmdSet" id="grpidMyMenuGroup"/>
        <!-- If you do not want to place the command in your own Group, 
             use Parent guid="guidCmdSet" id="grpidContextMain".
             These symbols are defined in GeneratedVSCT.vsct -->
        <CommandFlag>DynamicVisibility</CommandFlag>
        <Strings>
          <ButtonText>My Context Menu Command</ButtonText>
        </Strings>
      </Button>
    </Buttons>
    

    [!メモ]

    各ボタンまたはグループは GUID と整数 ID で識別されます。同じ GUID の複数のグループとボタンを作成する。ただし異なる ID が必要です。GUID の名前と ID <Symbols> ノードの実際の GUID と数値 ID に変換されます。

  3. ドメイン固有言語のコンテキストでのみ読み込まれるようにコマンドの表示の制約を追加します。詳細については、「VisibilityConstraints 要素」を参照してください。

    これを行うにはCommands の要素の後に CommandTable の要素に次の要素を追加します。

    <VisibilityConstraints>
      <!-- Ensures the command is only loaded for this DSL -->
      <VisibilityItem guid="guidCustomMenuCmdSet" id="cmdidMyContextMenuCommand"
        context="guidEditor"/>
    </VisibilityConstraints>
    
  4. guidsID で使用する名前を指定します。これを行うにはCommands の要素の後に CommandTable の要素の Symbols の要素を追加します。

    <Symbols>
      <!-- Substitute a unique GUID for the placeholder: -->
      <GuidSymbol name="guidCustomMenuCmdSet"
        value="{00000000-0000-0000-0000-000000000000}" >
        <IDSymbol name="grpidMyMenuGroup" value="0x01001"/>
        <IDSymbol name="cmdidMyContextMenuCommand" value="0x00001"/>
      </GuidSymbol>
    </Symbols>
    
  5. グループおよびメニュー項目を識別する GUID の {000...000} を置き換えます。新しい GUID を取得するには[ENT1ENT] メニューの [ENT0ENT] ツールを使用します。

    [!メモ]

    より多くのグループまたはメニュー項目を追加すると同じ GUID を使用できます。ただしIDSymbols の新しい値を使用する必要があります。

  6. このプロシージャからコピーしたコードでは独自の文字列に次の文字列の各文字列を置換します :

    • grpidMyMenuGroup

    • cmdidMyContextMenuCommand

    • guidCustomMenuCmdSet

    • My コンテキスト メニューのコマンド

Package.tt パッケージのバージョンを更新します。

コマンドを追加または変更するたびにドメイン固有言語の新バージョンをリリースする前にパッケージ クラスに適用される ProvideMenuResourceAttribute の version のパラメーターを更新します。

パッケージ クラスが生成されるファイルで定義されているためPackage.cs ファイルを生成するテキスト テンプレート ファイルの属性を更新します。

Package.tt ファイルを更新するには

  1. ソリューション エクスプローラー では***** DslPackage ***** プロジェクトでENT2ENT [入力] フォルダーでPackage.tt ファイルを開きます。

  2. ProvideMenuResource の属性を探します。

  3. 2 番目のパラメーターには属性の version のパラメーターをインクリメントします。必要に応じて目的を促すためのパラメーターの名前を明示的に記述できます。次に例を示します。

    [VSShell::ProvideMenuResource("1000.ctmenu", version: 2 )]

コマンドの動作を定義します。

DSL に既に DslPackage GeneratedCode \ \ CommandSet.cs で宣言された部分クラスに実装されるコマンドがあります。新しいコマンドを追加するには同じクラスの部分宣言を含む新しいファイルを作成してこのクラスを拡張する必要があります。クラスの名前は通常 <YourDslName> CommandSet です。クラスの名前を確認し内容を調べることによって開始されたことをお勧めします。

コマンド セットの CommandSet クラスはから派生します。

CommandSet のクラスを拡張します。

  1. 次にソリューション エクスプローラーでDslPackage プロジェクトでGeneratedCode フォルダーを開きCommandSet.tt の下に表示され生成されたファイル CommandSet.cs を開きます。そこで定義されているクラスの名前空間と名前を指定します。たとえば思えるかも知れません :

    namespace Company.Language1

    { ... internal partial class Language1CommandSet : ...

  2. *** DslPackage *** カスタム コードではという名前のフォルダーを作成します。このフォルダーにはCommandSet.cs という名前の新しいクラス ファイルを作成します。

  3. 新しいファイルに生成された部分クラスと同じ名前空間と名前の部分宣言を記述します。次に例を示します。

    namespace Company.Language1 /* Make sure this is correct */

    { internal partial class Language1CommandSet { ...

    新しいファイルを作成するためのクラス テンプレートを使用して メモ の名前空間とクラス名の両方を修正する必要があります。

Dd820681.collapse_all(ja-jp,VS.110).gifコマンド セットのクラスを拡張します。

コマンド セット コードは次の名前空間をインポートする必要があります :

using System;
using System.Collections.Generic;
using System.ComponentModel.Design; 
using System.Linq;
using Microsoft.VisualStudio.Modeling;
using Microsoft.VisualStudio.Modeling.Diagrams;
using Microsoft.VisualStudio.Modeling.Shell;

生成された CommandSet.cs と一致するように名前空間とクラス名を調整する :

namespace Company.Language1 /* Make sure this is correct */
{
  // Same class as the generated class.
  internal partial class Language1CommandSet 
  {

コマンドがコンテキスト メニューに表示されるコマンドを実行するなどがありますかを確認するには2 とおりの方法を定義する1。これらのメソッドがオーバーライドされています ; 代わりにコマンドのリストに登録します。

Dd820681.collapse_all(ja-jp,VS.110).gifコマンドが表示される場合に定義します。

各コマンドに対してコマンドがメニューに表示するかどうか有効にしたり灰色であるかどうかを確認 OnStatus... のメソッドを定義します。次の例に示すように MenuCommand の Visible と Enabled のプロパティを設定します。このメソッドはユーザーがダイアグラムを右クリックするためすばやく動作する必要があります。ショートカット メニューを作成するたびに呼び出されます。

この例ではコマンドで選択した要素の少なくとも 1 つが特定の状態にある場合にのみユーザーが図形の特定の型を選択すると有効になりますのみ表示され。たとえばクラス ダイアグラムの DSL のテンプレートに基づいておりClassShape と ModelClass はDSL で定義されている型です :

private void OnStatusMyContextMenuCommand(object sender, EventArgs e)
{
  MenuCommand command = sender as MenuCommand;
  command.Visible = command.Enabled = false;
  foreach (object selectedObject in this.CurrentSelection)
  {
    ClassShape shape = selectedObject as ClassShape;
    if (shape != null)
    {
      // Visibility depends on what is selected.
      command.Visible = true;
      ModelClass element = shape.ModelElement as ModelClass;
      // Enabled depends on state of selection.
      if (element != null && element.Comments.Count == 0)
      {
        command.Enabled = true;
        return; // seen enough
} } } }

次のフラグメントでは OnStatus のメソッドなどに便利です :

  • this.CurrentSelection.ユーザーが右クリックした図形はこのリストに常に含まれます。ユーザーが図の空白部分をクリックすると図はリスト内の唯一のメンバーです。

  • this.IsDiagramSelected() - ユーザーが図の空白部分をクリックした場合 true。

  • this.IsCurrentDiagramEmpty()

  • this.IsSingleSelection() - ユーザーが複数のオブジェクトを選択します。

  • this.SingleSelection - ユーザーが右クリックした図または図形

  • shape.ModelElement as MyLanguageElement - 図形によって表されるモデル要素。

一般的なガイドラインとしてVisible のプロパティを設定します。が依存する選択されている Enabled の要素のプロパティを選択した状態でら決です。

OnStatus のメソッドはストアの状態が変更されることはありません。

Dd820681.collapse_all(ja-jp,VS.110).gifコマンドの実行内容を定義します。

各コマンドに対してユーザーがをクリックすると必要なアクションを実行 OnMenu... のメソッドを定義します。

モデル要素を変更した場合トランザクション内で実行する必要があります。詳細については、「方法: ドメイン固有言語における標準のメニュー コマンドを修正する」を参照してください。

この例ではClassShapeModelClass と Comment はクラス図のユース テンプレートから派生したDSL で定義されている型です。

private void OnMenuMyContextMenuCommand(object sender, EventArgs e)
{
  MenuCommand command = sender as MenuCommand;
  Store store = this.CurrentDocData.Store;
  // Changes to elements and shapes must be performed in a Transaction.
  using (Transaction transaction =
       store.TransactionManager.BeginTransaction("My command"))
  {
    foreach (object selectedObject in this.CurrentSelection)
    {
      // ClassShape is defined in my DSL.
      ClassShape shape = selectedObject as ClassShape;
      if (shape != null)
      {
        // ModelClass is defined in my DSL.
        ModelClass element = shape.ModelElement as ModelClass;
        if (element != null)
        {
          // Do required action here - for example:

          // Create a new element. Comment is defined in my DSL.
          Comment newComment = new Comment(element.Partition);
          // Every element must be the target of an embedding link.
          element.ModelRoot.Comments.Add(newComment);
          // Set properties of new element.
          newComment.Text = "This is a comment";
          // Create a reference link to existing object.
          element.Comments.Add(newComment);
        }
      }
    }
    transaction.Commit(); // Don't forget this!
  }
}

モデルのオブジェクトからオブジェクトへとオブジェクトとのリンクを作成する方法の詳細については移動する方法 方法: ドメイン固有言語における標準のメニュー コマンドを修正する を参照してください。

Dd820681.collapse_all(ja-jp,VS.110).gifコマンドを登録します。

C# ではCommandSet.vsct のシンボルのセクションで指定した GUID と ID 値の宣言を繰り返して :

    private Guid guidCustomMenuCmdSet = 
        new Guid("00000000-0000-0000-0000-000000000000");
    private const int grpidMyMenuGroup = 0x01001;
    private const int cmdidMyContextMenuCommand = 1;

Commands.vsct で挿入した場合と同じ GUID 値を使用します。

[!メモ]

VSCT ファイルのシンボル セクションを変更する場合は照合にこれらの宣言を変更する必要があります。または Package.tt のバージョン番号をインクリメントする必要があります。

このコマンド セットの一部としてメニュー コマンドを登録します。GetMenuCommands() は図が初期化するときにが呼び出されます :

protected override IList<MenuCommand> GetMenuCommands()
{
  // Get the list of generated commands.
  IList<MenuCommand> commands = base.GetMenuCommands();
  // Add a custom command:
  DynamicStatusMenuCommand myContextMenuCommand =
    new DynamicStatusMenuCommand(
      new EventHandler(OnStatusMyContextMenuCommand),
      new EventHandler(OnMenuMyContextMenuCommand),
      new CommandID(guidCustomMenuCmdSet, cmdidMyContextMenuCommand));
  commands.Add(myContextMenuCommand);
  // Add more commands here.
  return commands;
} 

コマンドをテストします。

Visual Studio の実験用インスタンスでDSL をビルドして実行します。コマンドは指定された状況のショートカット メニューに表示されます。

コマンドを実行します。

  1. [入力] ENT0ENT ツール バーでENT1ENT [] をクリックします。

  2. ソリューションをビルドし直すためにデバッグを開始 F5 を実験用ビルドのドメイン固有言語をクリックします。

  3. の実験用ビルドではサンプル図を開きます。

  4. コマンドが正しく選択した項目によって適切に表示または非表示にする有効または無効になっていることを確認するには図のさまざまな項目を右クリックします。

トラブルシューティング

コマンドがメニューには :

  • コマンドはVisual Studio のデバッグ インスタンスでのみ DSL パッケージをインストールするまで表示されます。詳細については、「ドメイン固有言語ソリューションの配置」を参照してください。

  • 実験このサンプルに DSL の正しいファイル名拡張子があることを確認します。ファイル名拡張子を確認するにはVisual Studio のメイン インスタンスで DslDefinition.dsl を開きます。次にDSL のエクスプローラーでエディターのノードを右クリックし[プロパティ] をクリックします。[プロパティ] ウィンドウでFileExtension のプロパティを調べます。

  • パッケージのバージョン番号をインクリメントします。 か。

  • OnStatus のメソッドの先頭にブレークポイントを設定します。成果物は図の一部を右クリックしたときに中断されます。

    OnStatus のメソッドは呼び出されません :

    • CommandSet コードの GUID と ID が Commands.vsct のシンボルのセクションと一致することを確認します。

    • Commands.vsct では親ノードの GUID と ID が正しい親グループを識別してください。

    • Visual Studio コマンド プロンプトではdevenv exp /rootsuffix. " /setup " と入力します。次にVisual Studio のデバッグ インスタンスを再起動します。

  • このコマンドを確認するに OnStatus のメソッドをステップ実行します。表示されコマンド。enabled true に設定されます。

誤ったメニューのテキストが表示されますまたはコマンドが誤った場所に表示されます :

  • GUID と ID の組み合わせでこのコマンドで一意であることを確認します。

  • パッケージの旧バージョンをインストールされていることを確認します。

参照

概念

方法: ドメイン固有言語における標準のメニュー コマンドを修正する

その他の技術情報

ドメイン固有言語をカスタマイズするコードの記述