Поделиться через


Практическое руководство. Добавление команды в контекстное меню

Добавление команды меню в доменному язык (DSL) таким образом, чтобы пользователи могли выполнение задач, относящихся к конкретному DSL.Команды отображаются в меню контекста (ярлыка), если щелкнуть правой кнопкой мыши пользователей на схеме.Можно определить команду, чтобы оно появится в меню только в определенных обстоятельствах.Например, можно выполнять команды видимым только в случае, если пользователь нажимает конкретные типы элементов или элементы в определенных состояниях.

Вкратце, шаги выполняются в проекте DslPackage следующим образом:

  1. Объявите команду в Commands.vsct

  2. обновите номер версии пакета в Package.tt.Это необходимо делать при изменении Commands.vsct

  3. методы записи в классе CommandSet выполнять команды видимым и указать, что требуется команду выполнить.

Для образцов см. в разделе Визуализация и моделирование веб-узла SDK.

ПримечаниеПримечание

Можно также изменить поведение некоторых существующих команд вырезать и вставить, как выбрать все и печать путем переопределения методов в CommandSet.cs.Дополнительные сведения см. в разделе Практическое руководство. Изменение стандартной команды меню в доменном языке.

Определение команды использование MEF

Управляемое расширение .NET Framework (платформа MEF) предоставляет альтернативный метод определения команды меню в меню схема.Его основной целью включения DSL, которые будут расширение пользователем или другой стороны.Пользователи могут выбрать для установки только DSL либо могут устанавливаться и DSL и расширения.Однако MEF также снижает работы указание команд контекстного меню, после первоначального работы включить MEF на DSL.

Используйте метод в этом разделе, если:

  1. Необходимо указать команды меню в меню, отличном от контекстного меню, щелкните правой кнопкой мыши элемент.

  2. Необходимо определить конкретные группирования команд в меню.

  3. Не нужно, чтобы позволить другим, чтобы расширить DSL с собственными командами.

  4. Необходимо только указать одну команду.

В противном случае рассмотрите использование MEF метод для определения команды.Дополнительные сведения см. в разделе Расширение доменного языка с помощью MEF.

Объявите команду в Commands.Vsct

Команды меню, объявленные в DslPackage \ Commands.vsct.Эти определения определяют метки точек меню и, в котором они появляются в меню.

Файл, правка, Commands.vsct, импортировать определения из нескольких файлов, h, которые находятся в каталоге Пакет Visual Studio SDK устанавливает путь\ \ VisualStudioIntegration общее \ Inc.Он также включает GeneratedVsct.vsct, сформированное определения DSL.

Дополнительные сведения о файлах .vsct см. в разделе Файлы таблицы команд Visual Studio (.Vsct).

Добавление команды

  1. IN Обозреватель решенийпод DslPackage открыть проект, Commands.vsct.

  2. в Commands элемент определяет один или несколько кнопок и группу.A кнопка элемент меню.A группа раздел в меню.Для определения этих элементов добавьте следующие элементы:

    <!-- 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 и идентификатором integerМожно создать несколько групп и кнопок с тем же идентификатором GUID.Однако они должны иметь разные идентификаторы.Имена GUID и идентификатор GUID и преобразуются к фактическим числовые идентификаторы в <Символы> узел.

  3. Добавьте ограничение видимости для команды таким образом, что она будет загружен только в контексте конкретного доменного языка.Дополнительные сведения см. в разделе Элемент VisibilityConstraints.

    Для этого добавьте следующие элементы CommandTable элемент после Commands элемент.

    <VisibilityConstraints>
      <!-- Ensures the command is only loaded for this DSL -->
      <VisibilityItem guid="guidCustomMenuCmdSet" id="cmdidMyContextMenuCommand"
        context="guidEditor"/>
    </VisibilityConstraints>
    
  4. Укажите имена, которые можно использовать для guids и идентификаторы.Для этого добавьте a Symbols элемент CommandTable элемент после Commands элемент.

    <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. Заменить {000...000} с GUID, который определяет свои группы и пунктов меню.Чтобы получить новый идентификатор GUID, используйте Создать GUID средство на Сервис меню.

    ПримечаниеПримечание

    При добавлении нескольких групп или пунктов меню, можно использовать один и тот же идентификатор GUID.Однако необходимо использовать новые значения IDSymbols.

  6. В коде был скопирован из этой процедуры, замените все вхождения следующих строк с собственными строками.

    • grpidMyMenuGroup

    • cmdidMyContextMenuCommand

    • guidCustomMenuCmdSet

    • My команда контекстного меню

Обновить версию пакета в Package.tt

При добавлении или изменении команды обновления version параметр ProvideMenuResourceAttribute это применяется к классу пакета, прежде чем выпуске новой версии вашего доменного языка.

Поскольку класс пакета определяется в созданном файле, обновите атрибут в файле текстового шаблона, который создает файл Package.cs.

Обновление файла Package.tt

  1. IN Обозреватель решенийв DslPackage в проект GeneratedCode папка, открыть файл Package.tt.

  2. Найдите ProvideMenuResource атрибут.

  3. Увеличьте version параметр атрибута, второй параметр.При желании можно написать имя параметра, чтобы явно напомнить то его цели.Примеры.

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

Укажите расширение функциональности команды

Ваш DSL уже имеется несколько команд, которые выполняются в разделяемом классе, объявленного в DslPackage \ GeneratedCode \ CommandSet.cs.Чтобы добавить новые команды, необходимо расширить этот класс можно создать новый файл, содержащий частично объявление того же класса.Имя класса обычно YourDslNameCommandSet.Полезно начать с помощью имени класса и протестировать его содержимое.

Класс является производным из набора команд CommandSet.

Расширение класса CommandSet

  1. В обозревателе решений в проекте DslPackage, откройте папку GeneratedCode а затем разверните узел CommandSet.tt и откройте его созданный файл CommandSet.cs.Обратите внимание на пространство имен и имя первого класса, который определен в ней.Например, можно отобразить:

    namespace Company.Language1

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

  2. IN DslPackageсоздайте папку с именем пользовательским кодом.В этой папке создайте новый файл класса с именем CommandSet.cs.

  3. В новом файле, напишите объявление, частично имеет те же имя и пространство имен, что созданного разделяемого класса.Примеры.

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

    { internal partial class Language1CommandSet { ...

    Примечание.   Если используется шаблон класса для создания нового файла следует исправить и пространство имен и имя класса.

Dd820681.collapse_all(ru-ru,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 одного метода, чтобы определить, когда команда будет видна в контекстном меню, а другой для выполнения команды.Эти методы не переопределяют; вместо этого необходимо зарегистрировать их в списке команды.

Dd820681.collapse_all(ru-ru,VS.110).gifУкажите, когда команда будет видна

Для каждой команды, укажите OnStatus... метод, который определяет, является ли команда отображается в меню, и будет ли она включена или отображаются серым.Установка Visible и Enabled свойства MenuCommand, как показано в следующем примере.Этот метод вызывается для построения контекстное меню каждый раз, когда пользователь щелкнул правой кнопкой мыши схему, поэтому он должен работать быстро.

В этом примере команда отображается, только если пользователь выбрал указанный тип фигуры и включен только в том случае, если хотя бы один из выбранных элементов в указанном состоянии.Пример основан на шаблоне 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(ru-ru,VS.110).gifУкажите, что команда делает

Для каждой команды, укажите OnMenu... метод, который выполняет необходимую действие, когда пользователь выбирает соответствующую команду меню.

При внесении изменений к элементам модели необходимо сделать в транзакции.Дополнительные сведения см. в разделе Практическое руководство. Изменение стандартной команды меню в доменном языке.

В этом примере ClassShape" ModelClassи Comment типы, определенные в DSL, производный от шаблона 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(ru-ru,VS.110).gifЗарегистрируйте команда

Повторяющиеся в c# объявления GUID и значений идентификаторов, сделанное в разделе символов CommandSet.vsct:

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

Используйте одно и то же значение GUID вставленной в как Commands.vsct.

ПримечаниеПримечание

Если изменить раздел файла 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;
} 

Проверьте команда

Постройте и запустите DSL в экспериментальном экземпляре Visual Studio.Команда должна отображаться в контекстное меню в ситуациях.

Работа команды

  1. На Обозреватель решений на панели инструментов нажмите кнопку Преобразовать все шаблоны.

  2. Нажать F5 перестроить решение и запустить отладку доменный язык в экспериментальном построении.

  3. В экспериментальном построении, откройте схему.

  4. Элементы щелкните правой кнопкой мыши различные схемы для проверки, правильно команда включена или заблокирована, и соответствующим образом показано или скрыть, в зависимости от выбранного элемента.

Устранение неполадок

Команда не отображается в меню:

  • Команда отображается только в экземпляры отладки Visual Studio, до тех пор, пока не устанавливается пакет DSL.Дополнительные сведения см. в разделе Развертывание решений на доменных языках.

  • Убедитесь, что в экспериментальном пример содержит нужное расширение имени файла для данного DSL.Чтобы проверить расширение имени файла, откройте DslDefinition.dsl в основном экземпляре Visual Studio.Затем в обозревателе DSL, щелкните правой кнопкой мыши узел редактор, а затем щелкните свойства.В окне свойства проверьте свойство FileExtension.

  • Выполнил пользователя увеличить номер версии пакета-

  • Установите точку останова в начале данного метода OnStatus.Он должен прервать выполнение при щелчке правой кнопкой мыши над любой части схемы.

    Метод OnStatus не вызывается.

    • Убедитесь, что идентификаторы GUID и идентификаторы в коде CommandSet соответствуют в разделе Commands.vsct символов.

    • В Commands.vsct убедитесь, что идентификатор GUID и идентификатор в любом родительском узле определяют правильную родительскую группу.

    • В командной строке Visual Studio, введите /rootsuffix - параметр devenv exp /setup.Перезапустите экземпляр отладки Visual Studio.

  • Переход с помощью метода OnStatus для проверки этой команды. Visible и команд. Enabled имеет значение true.

Неправильный текст меню отображается или команда отображается в неправильное расположение.

  • Убедитесь, что идентификатор GUID и уникальное сочетание в этой команде.

  • Убедитесь, что удалении более ранние версии пакета.

См. также

Основные понятия

Практическое руководство. Изменение стандартной команды меню в доменном языке

Другие ресурсы

Написание кода для настройки доменного языка

Образец кода: принципиальные схемы