Практическое руководство. Добавление команды в контекстное меню
Добавление команды меню в доменному язык (DSL) таким образом, чтобы пользователи могли выполнение задач, относящихся к конкретному DSL.Команды отображаются в меню контекста (ярлыка), если щелкнуть правой кнопкой мыши пользователей на схеме.Можно определить команду, чтобы оно появится в меню только в определенных обстоятельствах.Например, можно выполнять команды видимым только в случае, если пользователь нажимает конкретные типы элементов или элементы в определенных состояниях.
Вкратце, шаги выполняются в проекте DslPackage следующим образом:
Объявите команду в Commands.vsct
обновите номер версии пакета в Package.tt.Это необходимо делать при изменении Commands.vsct
методы записи в классе CommandSet выполнять команды видимым и указать, что требуется команду выполнить.
Для образцов см. в разделе Визуализация и моделирование веб-узла SDK.
Примечание |
---|
Можно также изменить поведение некоторых существующих команд вырезать и вставить, как выбрать все и печать путем переопределения методов в CommandSet.cs.Дополнительные сведения см. в разделе Практическое руководство. Изменение стандартной команды меню в доменном языке. |
Определение команды использование MEF
Управляемое расширение .NET Framework (платформа MEF) предоставляет альтернативный метод определения команды меню в меню схема.Его основной целью включения DSL, которые будут расширение пользователем или другой стороны.Пользователи могут выбрать для установки только DSL либо могут устанавливаться и DSL и расширения.Однако MEF также снижает работы указание команд контекстного меню, после первоначального работы включить MEF на DSL.
Используйте метод в этом разделе, если:
Необходимо указать команды меню в меню, отличном от контекстного меню, щелкните правой кнопкой мыши элемент.
Необходимо определить конкретные группирования команд в меню.
Не нужно, чтобы позволить другим, чтобы расширить DSL с собственными командами.
Необходимо только указать одну команду.
В противном случае рассмотрите использование MEF метод для определения команды.Дополнительные сведения см. в разделе Расширение доменного языка с помощью MEF.
Объявите команду в Commands.Vsct
Команды меню, объявленные в DslPackage \ Commands.vsct.Эти определения определяют метки точек меню и, в котором они появляются в меню.
Файл, правка, Commands.vsct, импортировать определения из нескольких файлов, h, которые находятся в каталоге Пакет Visual Studio SDK устанавливает путь\ \ VisualStudioIntegration общее \ Inc.Он также включает GeneratedVsct.vsct, сформированное определения DSL.
Дополнительные сведения о файлах .vsct см. в разделе Файлы таблицы команд Visual Studio (.Vsct).
Добавление команды
IN Обозреватель решенийпод DslPackage открыть проект, Commands.vsct.
в 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 и преобразуются к фактическим числовые идентификаторы в <Символы> узел.
Добавьте ограничение видимости для команды таким образом, что она будет загружен только в контексте конкретного доменного языка.Дополнительные сведения см. в разделе Элемент VisibilityConstraints.
Для этого добавьте следующие элементы CommandTable элемент после Commands элемент.
<VisibilityConstraints> <!-- Ensures the command is only loaded for this DSL --> <VisibilityItem guid="guidCustomMenuCmdSet" id="cmdidMyContextMenuCommand" context="guidEditor"/> </VisibilityConstraints>
Укажите имена, которые можно использовать для 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>
Заменить {000...000} с GUID, который определяет свои группы и пунктов меню.Чтобы получить новый идентификатор GUID, используйте Создать GUID средство на Сервис меню.
Примечание При добавлении нескольких групп или пунктов меню, можно использовать один и тот же идентификатор GUID.Однако необходимо использовать новые значения IDSymbols.
В коде был скопирован из этой процедуры, замените все вхождения следующих строк с собственными строками.
grpidMyMenuGroup
cmdidMyContextMenuCommand
guidCustomMenuCmdSet
My команда контекстного меню
Обновить версию пакета в Package.tt
При добавлении или изменении команды обновления version параметр ProvideMenuResourceAttribute это применяется к классу пакета, прежде чем выпуске новой версии вашего доменного языка.
Поскольку класс пакета определяется в созданном файле, обновите атрибут в файле текстового шаблона, который создает файл Package.cs.
Обновление файла Package.tt
IN Обозреватель решенийв DslPackage в проект GeneratedCode папка, открыть файл Package.tt.
Найдите ProvideMenuResource атрибут.
Увеличьте version параметр атрибута, второй параметр.При желании можно написать имя параметра, чтобы явно напомнить то его цели.Примеры.
[VSShell::ProvideMenuResource("1000.ctmenu", version: 2 )]
Укажите расширение функциональности команды
Ваш DSL уже имеется несколько команд, которые выполняются в разделяемом классе, объявленного в DslPackage \ GeneratedCode \ CommandSet.cs.Чтобы добавить новые команды, необходимо расширить этот класс можно создать новый файл, содержащий частично объявление того же класса.Имя класса обычно YourDslNameCommandSet.Полезно начать с помощью имени класса и протестировать его содержимое.
Класс является производным из набора команд CommandSet.
Расширение класса CommandSet
В обозревателе решений в проекте DslPackage, откройте папку GeneratedCode а затем разверните узел CommandSet.tt и откройте его созданный файл CommandSet.cs.Обратите внимание на пространство имен и имя первого класса, который определен в ней.Например, можно отобразить:
namespace Company.Language1
{ ... internal partial class Language1CommandSet : ...
IN DslPackageсоздайте папку с именем пользовательским кодом.В этой папке создайте новый файл класса с именем CommandSet.cs.
В новом файле, напишите объявление, частично имеет те же имя и пространство имен, что созданного разделяемого класса.Примеры.
namespace Company.Language1 /* Make sure this is correct */
{ internal partial class Language1CommandSet { ...
Примечание. Если используется шаблон класса для создания нового файла следует исправить и пространство имен и имя класса.
Расширяет класс набора команд
Код набора команд, как правило необходимо импортировать следующие пространства имен:
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 одного метода, чтобы определить, когда команда будет видна в контекстном меню, а другой для выполнения команды.Эти методы не переопределяют; вместо этого необходимо зарегистрировать их в списке команды.
Укажите, когда команда будет видна
Для каждой команды, укажите 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 не должен изменить состояние хранилища.
Укажите, что команда делает
Для каждой команды, укажите 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!
}
}
Дополнительные сведения о способах перехода из объекта в объект в модели, и о том, как создавать объекты и связи, см. в разделе Практическое руководство. Изменение стандартной команды меню в доменном языке.
Зарегистрируйте команда
Повторяющиеся в 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.Команда должна отображаться в контекстное меню в ситуациях.
Работа команды
На Обозреватель решений на панели инструментов нажмите кнопку Преобразовать все шаблоны.
Нажать F5 перестроить решение и запустить отладку доменный язык в экспериментальном построении.
В экспериментальном построении, откройте схему.
Элементы щелкните правой кнопкой мыши различные схемы для проверки, правильно команда включена или заблокирована, и соответствующим образом показано или скрыть, в зависимости от выбранного элемента.
Устранение неполадок
Команда не отображается в меню:
Команда отображается только в экземпляры отладки 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 и уникальное сочетание в этой команде.
Убедитесь, что удалении более ранние версии пакета.
См. также
Основные понятия
Практическое руководство. Изменение стандартной команды меню в доменном языке