Добавление элементов пользовательского интерфейса в VSPackages

VSPackage может добавлять элементы пользовательского интерфейса, например меню, панели инструментов и окна инструментов, в Visual Studio с помощью VSCT-файла .

Рекомендации по проектированию элементов пользовательского интерфейса можно найти в рекомендациях по пользовательскому интерфейсу Visual Studio.

Архитектура командной таблицы Visual Studio

Как отмечалось, архитектура таблицы команд поддерживает основные принципы архитектуры. Текеты, лежащие в основе абстракций, структур данных и средств архитектуры таблицы команд, приведены следующим образом:

  • Существует три основных типа элементов: меню, команды и группы. Меню можно предоставлять в пользовательском интерфейсе в виде меню, подменю, панелей инструментов или окон инструментов. Команды — это процедуры, которые пользователь может выполнять в интегрированной среде разработки, и их можно предоставлять в виде элементов меню, кнопок, списков или других элементов управления. Группы — это контейнеры для меню и команд.

  • Каждый элемент определяется определением, описывающим элемент, его приоритет относительно других элементов и флаги, изменяющие его поведение.

  • Каждый элемент содержит размещение, описывающее родительский элемент элемента. Элемент может содержать несколько родителей, чтобы оно отображалось в нескольких расположениях в пользовательском интерфейсе.

Каждая команда должна иметь группу в качестве родительского элемента, даже если она является единственным дочерним элементом в этой группе. Каждое стандартное меню также должно иметь родительскую группу. Панели инструментов и окна инструментов действуют как собственные родители. Группа может быть в качестве родительской главной строки меню Visual Studio или любого меню, панели инструментов или окна инструментов.

Определение элементов

VSCT-файл форматируется в ФОРМАТЕ XML. Он определяет элементы пользовательского интерфейса для пакета и определяет, где эти элементы отображаются в интегрированной среде разработки. Каждое меню, группа или команда в пакете сначала назначает идентификатор GUID и идентификатор в Symbols разделе. В остальной части VSCT-файла каждое меню, команды и группы определяется его сочетанием GUID и идентификатора. В следующем примере показан типичный Symbols раздел, созданный шаблоном пакета Visual Studio при выборе команды меню в шаблоне.

<Symbols>
  <!-- This is the package guid. -->
  <GuidSymbol name="guidMenuTextPkg" value="{b1253bc6-d266-402b-89e7-5e3d3b22c746}" />

  <!-- This is the guid used to group the menu commands together -->
  <GuidSymbol name="guidMenuTextCmdSet" value="{a633d4e4-6c65-4436-a138-1abeba7c9a69}">
    <IDSymbol name="MyMenuGroup" value="0x1020" />
    <IDSymbol name="cmdidMyCommand" value="0x0100" />
  </GuidSymbol>

  <GuidSymbol name="guidImages" value="{53323d9a-972d-4671-bb5b-9e418480922f}">
    <IDSymbol name="bmpPic1" value="1" />
    <IDSymbol name="bmpPic2" value="2" />
    <IDSymbol name="bmpPicSearch" value="3" />
    <IDSymbol name="bmpPicX" value="4" />
    <IDSymbol name="bmpPicArrows" value="5" />
  </GuidSymbol>
</Symbols>

Элемент верхнего уровня раздела — это элемент SymbolsGuidSymbol. GuidSymbol элементы сопоставляют имена с идентификаторами GUID, которые используются интегрированной средой разработки для идентификации пакетов и их компонентов.

Примечание.

Идентификаторы GUID создаются автоматически шаблоном пакета Visual Studio. Вы также можете создать уникальный ИДЕНТИФИКАТОР GUID, щелкнув "Создать GUID " в меню "Сервис ".

Первый GuidSymbol элемент — guid<PackageName>Pkgэто GUID самого пакета. Это GUID, используемый Visual Studio для загрузки пакета. Как правило, у него нет дочерних элементов.

По соглашению меню и команды группируются под вторым GuidSymbol элементом, guid<PackageName>CmdSetа растровые изображения находятся под третьим GuidSymbol элементом guidImages. Вам не нужно следовать этому соглашению, но каждое меню, группа, команда и растровое изображение должно быть дочерним элементом GuidSymbol .

Во втором GuidSymbol элементе, представляющего набор команд пакета, есть несколько IDSymbol элементов. Каждый элемент IDSymbol сопоставляет имя числовым значением и может представлять меню, группу или команду, которая входит в набор команд. Элементы IDSymbol в третьем GuidSymbol элементе представляют растровые изображения, которые могут использоваться в качестве значков для команд. Так как пары GUID/ID должны быть уникальными в приложении, два дочерних элемента одного и того же элемента могут иметь одно и то же GuidSymbol значение.

Если меню, группа или команда имеют GUID и идентификатор, его можно добавить в интегрированную среду разработки. Каждый элемент пользовательского интерфейса должен иметь следующие элементы:

  • Атрибут guid , соответствующий имени элемента, в который определяется элемент пользовательского GuidSymbol интерфейса.

  • Атрибут id , соответствующий имени связанного IDSymbol элемента.

Вместе и guidid атрибуты составляют сигнатуру элемента пользовательского интерфейса.

  • Атрибут priority , определяющий размещение элемента пользовательского интерфейса в родительском меню или группе.

  • Элемент Parent , имеющий guid и id атрибуты, указывающие подпись родительского меню или группы.

Каждое меню определяется как элемент Menu в Menus разделе. Меню должны иметь guidи idатрибуты, а priorityParent также элемент, а также следующие дополнительные атрибуты и дочерние элементы:

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

  • Элемент Strings, содержащий элемент ButtonText, указывающий название меню в интегрированной среде разработки и элемент CommandName, указывающий имя, которое используется в окне command для доступа к меню.

  • Необязательные флаги. Элемент CommandFlag может отображаться в определении меню, чтобы изменить его внешний вид или поведение в интегрированной среде разработки.

Каждый Menu элемент должен иметь группу в качестве родительского элемента, если он не является закрепленным элементом, таким как панель инструментов. Закрепления меню является собственным родительским элементом. Дополнительные сведения о меню и значениях атрибута type см. в документации по элементу Menu.

В следующем примере показано меню, которое отображается в строке меню Visual Studio рядом с меню "Сервис ".

<Menu guid="guidTopLevelMenuCmdSet" id="TopLevelMenu" priority="0x700" type="Menu">
  <Parent guid="guidSHLMainMenu" id="IDG_VS_MM_TOOLSADDINS" />
  <Strings>
    <ButtonText>TestMenu</ButtonText>
    <CommandName>TestMenu</CommandName>
  </Strings>
</Menu>

Группы

Группа — это элемент, определенный в Groups разделе VSCT-файла . Группы — это просто контейнеры. Они не отображаются в интегрированной среде разработки, за исключением разделительной строки в меню. Поэтому элемент Group определяется только его сигнатурой, приоритетом и родительским элементом.

Группа может иметь меню, другую группу или саму группу как родительскую. Однако родительский элемент обычно представляет собой меню или панель инструментов. Меню в предыдущем примере является дочерним элементом группы, и эта группа является дочерним IDG_VS_MM_TOOLSADDINS элементом строки меню Visual Studio. Группа в следующем примере является дочерним элементом меню в предыдущем примере.

<Group guid="guidTopLevelMenuCmdSet" id="MyMenuGroup" priority="0x0600">
  <Parent guid="guidTopLevelMenuCmdSet" id="TopLevelMenu"/>
</Group>

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

<Menu guid="guidTopLevelMenuCmdSet" id="SubMenu" priority="0x0100" type="Menu">
  <Parent guid="guidTopLevelMenuCmdSet" id="MyMenuGroup"/>
  <Strings>
    <ButtonText>Sub Menu</ButtonText>
    <CommandName>Sub Menu</CommandName>
  </Strings>
</Menu>

Команды

Команда, предоставляемая интегрированной среде разработки, определяется как элемент Button или элемент Combo. Чтобы появиться в меню или панели инструментов, команда должна иметь группу в качестве родительского элемента.

Пуговицы

Кнопки определены в Buttons разделе. Любой элемент меню, кнопка или другой элемент, который пользователь щелкает, чтобы выполнить одну команду, считается кнопкой. Некоторые типы кнопок также могут включать функции списка. Кнопки имеют одинаковые обязательные и необязательные атрибуты, которые имеют меню, а также могут иметь элемент Icon, указывающий GUID и идентификатор растрового изображения, представляющего кнопку в интегрированной среде разработки. Дополнительные сведения о кнопках и их атрибутах см. в документации по элементам Button.

Кнопка в следующем примере является дочерним элементом группы в предыдущем примере и будет отображаться в интегрированной среде разработки в качестве элемента меню в родительском меню этой группы.

<Button guid="guidTopLevelMenuCmdSet" id="cmdidTestCommand" priority="0x0100" type="Button">
  <Parent guid="guidTopLevelMenuCmdSet" id="MyMenuGroup" />
  <Icon guid="guidImages" id="bmpPic1" />
  <Strings>
    <CommandName>cmdidTestCommand</CommandName>
    <ButtonText>Test Command</ButtonText>
  </Strings>
</Button>
Комбо

Списки определяются в Combos разделе. Каждый Combo элемент представляет раскрывающийся список в интегрированной среде разработки. Поле списка может быть или не может быть записываемым пользователями в зависимости от значения атрибута type со списком. Комбо имеют те же элементы и поведение, что и кнопки, а также могут иметь следующие дополнительные атрибуты:

  • Атрибут, указывающий defaultWidth ширину пикселей.

  • Атрибут idCommandList , указывающий список, содержащий элементы, отображаемые в поле списка. Список команд должен быть объявлен на том же GuidSymbol узле, где содержится список со списком.

В следующем примере определяется элемент со списком.

<Combos>
  <Combo guid="guidFirstToolWinCmdSet"
         id="cmdidWindowsMediaFilename"
         priority="0x0100" type="DynamicCombo"
         idCommandList="cmdidWindowsMediaFilenameGetList"
         defaultWidth="130">
    <Parent guid="guidFirstToolWinCmdSet"
            id="ToolbarGroupID" />
    <CommandFlag>IconAndText</CommandFlag>
    <CommandFlag>CommandWellOnly</CommandFlag>
    <CommandFlag>StretchHorizontally</CommandFlag>
    <Strings>
      <CommandName>Filename</CommandName>
      <ButtonText>Enter a Filename</ButtonText>
    </Strings>
  </Combo>
</Combos>
Растровые изображения

Команды, которые будут отображаться вместе со значком, должны содержать Icon элемент, ссылающийся на растровое изображение с помощью идентификатора GUID и идентификатора. Каждое растровое изображение определяется как элемент Bitmap в Bitmaps разделе. Единственными обязательными атрибутами для Bitmap определения являются guid и href, указывающие на исходный файл. Если исходный файл является полосой ресурсов, атрибут usedList также требуется для перечисления доступных изображений в полосе. Дополнительные сведения см. в документации по элементу Bitmap.

Установление родительских связей

Следующие правила определяют способ вызова другого элемента в качестве родительского элемента.

Элемент Определено в этом разделе командной таблицы Может содержаться (в качестве родительского или размещения в разделе или обоих CommandPlacements ) Может содержать (называется родительским)
Групповой Элемент Groups, интегрированная среда разработки, другие VSPackages Меню, группа, сам элемент Меню, группы и команды
Меню Элемент Menus, интегрированная среда разработки, другие VSPackages От 1 до n групп От 0 до n групп
Панель инструментов Элемент Menus, интегрированная среда разработки, другие VSPackages Сам элемент От 0 до n групп
Menu Item Элемент Button, интегрированная среда разработки, другие VSPackages От 1 до n групп, сам элемент -0 до n групп
Кнопка Элемент Button, интегрированная среда разработки, другие VSPackages От 1 до n групп, сам элемент
Комбо Элемент Combos, интегрированная среда разработки, другие VSPackages От 1 до n групп, сам элемент

Меню, группа или команда могут отображаться в нескольких расположениях в интегрированной среде разработки. Чтобы элемент отображался в нескольких расположениях, его необходимо добавить CommandPlacements в раздел как элемент CommandPlacement. Любое меню, группа или команда можно добавить в качестве размещения команд. Однако панели инструментов нельзя размещать таким образом, так как они не могут отображаться в нескольких расположениях с учетом контекста.

Расположения команд имеют guididpriority и атрибуты. Идентификатор GUID и идентификатор должны соответствовать идентификатору элемента, расположенного. Атрибут priority управляет размещением элемента относительно других элементов. Если интегрированная среда разработки объединяет два или более элементов с одинаковым приоритетом, их размещение не определено, так как интегрированная среда разработки не гарантирует, что ресурсы пакета считываются в одном порядке при каждом построении пакета.

Если меню или группа отображаются в нескольких расположениях, все дочерние элементы этого меню или группы будут отображаться в каждом экземпляре.

Видимость команд и контекст

При установке нескольких VSPackage не только меню, но и элементов меню и панелей инструментов может загромождать интегрированную среду разработки. Чтобы избежать этой проблемы, можно управлять видимостью отдельных элементов пользовательского интерфейса с помощью ограничений видимости и флагов команд.

Ограничения видимости

Ограничение видимости устанавливается как элемент VisibilityItem в VisibilityConstraints разделе. Ограничение видимости определяет определенные контексты пользовательского интерфейса, в которых отображается целевой элемент. Меню или команда, включенная в этот раздел, отображается только в том случае, если один из определенных контекстов активен. Если меню или команда не ссылается в этом разделе, она всегда отображается по умолчанию. Этот раздел не применяется к группам.

VisibilityItem элементы должны иметь три атрибута: guid и id целевой элемент пользовательского интерфейса, а также context. Атрибут context указывает, когда целевой элемент будет видимым, и принимает любой допустимый контекст пользовательского интерфейса в качестве значения. Константы контекста пользовательского VSConstants интерфейса для Visual Studio являются членами класса. Каждый VisibilityItem элемент может принимать только одно значение контекста. Чтобы применить второй контекст, создайте второй VisibilityItem элемент, указывающий на тот же элемент, как показано в следующем примере.

<VisibilityConstraints>
  <VisibilityItem guid="guidSolutionToolbarCmdSet"
        id="cmdidTestCmd"
        context="UICONTEXT_SolutionHasSingleProject" />
  <VisibilityItem guid="guidSolutionToolbarCmdSet"
        id="cmdidTestCmd"
        context="UICONTEXT_SolutionHasMultipleProjects" />
</VisibilityConstraints>

Флаги команд

Следующие флаги команд могут повлиять на видимость меню и команд, к которые они применяются.

AlwaysCreate Меню создается, даже если у него нет групп или кнопок.

Допустимо для: Menu

CommandWellOnly Примените этот флаг, если команда не отображается в меню верхнего уровня, и вы хотите сделать ее доступной для дополнительной настройки оболочки, например привязывая ее к ключу. После установки VSPackage пользователь может настроить эти команды, открыв диалоговое окно "Параметры " и изменив размещение команд в категории "Среда клавиатуры". Не влияет на размещение в контекстных меню, панели инструментов, контроллеры меню или подменю.

Допустимо для: Button, Combo

DefaultDisabled По умолчанию команда отключена, если VSPackage, реализующий команду, не загружена или метод QueryStatus не был вызван.

Допустимо для: Button, Combo

DefaultInvisible По умолчанию команда невидима, если VSPackage, реализующий команду, не загружена или метод QueryStatus не был вызван.

Должен сочетаться с флагом DynamicVisibility .

Допустимо для: Button, ComboMenu

DynamicVisibility Видимость команды можно изменить с помощью QueryStatus метода или GUID контекста, включенного в VisibilityConstraints раздел.

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

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

Должен сочетаться с флагом DefaultInvisible .

Допустимо для: Button, ComboMenu

NoShowOnMenuController Если команда с этим флагом находится в контроллере меню, команда не отображается в раскрывающемся списке.

Допустимо для: Button

Дополнительные сведения о флагах команд см. в документации по элементу CommandFlag.

Общие требования

Перед отображением и включением команды необходимо передать следующую серию тестов:

  • Команда правильно размещена.

  • Флаг DefaultInvisible не задан.

  • Родительское меню или панель инструментов отображается.

  • Команда невидима из-за записи контекста в разделе элемента VisibilityConstraints.

  • Код VSPackage, реализующий IOleCommandTarget интерфейс, отображает и включает команду. Код интерфейса не перехватил его и действовал на нем.

  • Когда пользователь щелкает команду, она становится предметом процедуры, описанной в алгоритме маршрутизации.

Вызов предварительно определенных команд

Элемент UsedCommands позволяет VSPackages получать доступ к командам, предоставляемым другими пакетами VSPackage или интегрированной среды разработки. Для этого создайте элемент UsedCommand с идентификатором GUID и идентификатором команды для использования. Это гарантирует, что команда будет загружена Visual Studio, даже если она не входит в текущую конфигурацию Visual Studio. Дополнительные сведения см. в разделе "Элемент UsedCommand".

Внешний вид элемента интерфейса

Рекомендации по выбору и расположению элементов команд приведены следующим образом:

  • Visual Studio предлагает множество элементов пользовательского интерфейса, которые отображаются по-разному в зависимости от размещения.

  • Элемент пользовательского интерфейса, определенный с помощью DefaultInvisible флага, не будет отображаться в интегрированной среде разработки, если он не отображается реализацией VSPackage метода или связан с определенным контекстом пользовательского QueryStatus интерфейса в VisibilityConstraints разделе.

  • Даже команда с успешной позицией может не отображаться. Это связано с тем, что интегрированная среда разработки автоматически скрывает или отображает некоторые команды в зависимости от интерфейсов, которые в VSPackage реализованы (или не реализованы). Например, реализация VSPackage некоторых интерфейсов сборки приводит к автоматическому отображению элементов меню, связанных со сборкой.

  • CommandWellOnly Применение флага в определении элемента пользовательского интерфейса означает, что команда может быть добавлена только путем настройки.

  • Команды могут быть доступны только в определенных контекстах пользовательского интерфейса, например, только если диалоговое окно отображается, когда интегрированная среда разработки находится в режиме конструктора.

  • Чтобы некоторые элементы пользовательского интерфейса отображались в интегрированной среде разработки, необходимо реализовать один или несколько интерфейсов или написать код.