Использование контекста пользовательского интерфейса на основе правил для расширений Visual Studio
Visual Studio позволяет загружать ПАКЕТЫ VSPackage при активации определенных известных UIContextобъектов. Однако эти контексты пользовательского интерфейса не являются точными, что оставляет авторов расширений без выбора, но выбрать доступный контекст пользовательского интерфейса, активируемый до точки, которую они действительно хотели загрузить VSPackage. Список известных контекстов пользовательского интерфейса см. в разделе KnownUIContexts.
Загрузка пакетов может повлиять на производительность и загружать их раньше, чем требуется, не рекомендуется. Visual Studio 2015 представила концепцию контекстов пользовательского интерфейса на основе правил, механизм, позволяющий авторам расширений определять точные условия, при которых активируется контекст пользовательского интерфейса и загружаются связанные vsPackages.
Контекст пользовательского интерфейса на основе правил
Правило состоит из нового контекста пользовательского интерфейса (GUID) и логического выражения, ссылающегося на один или несколько терминов в сочетании с логическими "и", "или", "не" операциями. Термины оцениваются динамически во время выполнения, и выражение повторно вычисляется при каждом изменении его терминов. Когда выражение оценивается как true, активируется связанный контекст пользовательского интерфейса. В противном случае контекст пользовательского интерфейса будет удален.
Контекст пользовательского интерфейса на основе правил можно использовать различными способами:
Укажите ограничения видимости для команд и окон инструментов. Вы можете скрыть окна команд и инструментов, пока не будет выполнено правило контекста пользовательского интерфейса.
В качестве ограничений автозагрузки: пакеты автозагрузки выполняются только в том случае, если правило выполняется.
Как отложенная задача: задержка загрузки до тех пор, пока указанный интервал не пройдет, и правило по-прежнему выполняется.
Механизм может использоваться любым расширением Visual Studio.
Создание контекста пользовательского интерфейса на основе правил
Предположим, у вас есть расширение TestPackage, которое предлагает команду меню, которая применяется только к файлам с расширением config . До VS2015 лучше всего загрузить TestPackage при SolutionExistsAndFullyLoadedContext активации контекста пользовательского интерфейса. Загрузка TestPackage таким образом не эффективна, так как загруженное решение может даже не содержать файл конфигурации .config . В этих шагах показано, как контекст пользовательского интерфейса на основе правил можно использовать для активации контекста пользовательского интерфейса только при выборе файла с расширением конфигурации .config и загрузке TestPackage при активации этого контекста пользовательского интерфейса.
Определите новый GUID UIContext и добавьте его в класс ProvideAutoLoadAttribute VSPackage и ProvideUIContextRuleAttribute.
Например, предположим, что будет добавлен новый UIContext "UIContextGuid". Созданный GUID (можно создать GUID, щелкнув "Сервис>создать GUID") — "8B40D5E2-5626-42AE-99EF-3DD1EFF46E7B". Затем вы добавите следующее объявление в класс пакета:
public const string UIContextGuid = "8B40D5E2-5626-42AE-99EF-3DD1EFF46E7B";
Для атрибутов добавьте следующие значения: (Подробные сведения об этих атрибутах будут описаны позже)
[ProvideAutoLoad(TestPackage.UIContextGuid)] [ProvideUIContextRule(TestPackage.UIContextGuid, name: "Test auto load", expression: "DotConfig", termNames: new[] { "DotConfig" }, termValues: new[] { "HierSingleSelectionName:.config$" })]
Эти метаданные определяют новый GUID UIContext (8B40D5E2-5626-42AE-99EF-3DD1EFF46E7B) и выражение, ссылающееся на один термин DotConfig. Термин DotConfig имеет значение true, если текущий выбор в активной иерархии имеет имя, соответствующее шаблону регулярного выражения "\.config$" (заканчивается конфигурацией .config). Значение (по умолчанию) определяет необязательное имя правила, полезного для отладки.
Значения атрибута добавляются в pkgdef, созданные во время сборки после этого.
В VSCT-файле для команд TestPackage добавьте флаг DynamicVisibility в соответствующие команды:
<CommandFlag>DynamicVisibility</CommandFlag>
В разделе VisibilityConstraints VSCT привязать соответствующие команды к новому GUID UIContext, определенному в #1:
<VisibilityConstraints> <VisibilityItem guid="guidTestPackageCmdSet" id="TestId" context="UIContextGuid"/> </VisibilityConstraints>
В разделе "Символы" добавьте определение UIContext:
<GuidSymbol name="UIContextGuid" value="{8B40D5E2-5626-42AE-99EF-3DD1EFF46E7B}" />
Теперь команды контекстного меню для файлов конфигурации *.config будут видимы только в том случае, если выбранный элемент в обозревателе решений является файлом конфигурации . Пакет не будет загружен до тех пор, пока не будет выбрана одна из этих команд.
Затем используйте отладчик, чтобы убедиться, что пакет загружается только в том случае, если он ожидается. Отладка TestPackage:
Задайте точку останова в методе Initialize .
Создайте TestPackage и запустите отладку.
Создайте проект или откройте его.
Выберите любой файл с расширением, отличном от config. Точка останова не должна быть достигнута.
Выберите файл App.Config.
TestPackage загружает и останавливается в точке останова.
Добавление дополнительных правил для контекста пользовательского интерфейса
Так как правила контекста пользовательского интерфейса являются логическими выражениями, можно добавить более ограниченные правила для контекста пользовательского интерфейса. Например, в приведенном выше контексте пользовательского интерфейса можно указать, что правило применяется только при загрузке решения с проектом. Таким образом, команды не будут отображаться, если открыть файл конфигурации как автономный файл, а не как часть проекта.
[ProvideAutoLoad(TestPackage.UIContextGuid)]
[ProvideUIContextRule(TestPackage.UIContextGuid,
name: "Test auto load",
expression: "(SingleProject | MultipleProjects) & DotConfig",
termNames: new[] { "SingleProject", "MultipleProjects","DotConfig" },
termValues: new[] { VSConstants.UICONTEXT.SolutionHasSingleProject_string , VSConstants.UICONTEXT.SolutionHasMultipleProjects_string , "HierSingleSelectionName:.config$" })]
Теперь выражение ссылается на три термина. Первые два термина " SingleProject" и "MultipleProjects", ссылаются на другие хорошо известные контексты пользовательского интерфейса (по идентификаторам GUID). Третий термин DotConfig — это контекст пользовательского интерфейса на основе правил, определенный ранее в этой статье.
Задержка активации
Правила могут иметь необязательное значение "Задержка". Задержка указывается в миллисекундах. В этом случае задержка приводит к задержке активации или деактивации контекста пользовательского интерфейса правила. Если правило изменяется до интервала задержки, то ничего не происходит. Этот механизм можно использовать для выполнения шагов инициализации ,особенно однократной инициализации без учета таймеров или регистрации для уведомлений об простое.
Например, можно указать правило тестовой нагрузки с задержкой в 100 миллисекундах:
[ProvideAutoLoad(TestPackage.UIContextGuid)]
[ProvideUIContextRule(TestPackage.UIContextGuid,
name: "Test auto load",
expression: "DotConfig",
termNames: new[] { "DotConfig" },
termValues: new[] { "HierSingleSelectionName:.config$" },
delay: 100)]
Типы терминов
Ниже приведены различные типы поддерживаемых терминов:
Срок | Description |
---|---|
{nn-nnnn-nnnn-nnnn-nnnn-nn} | GUID ссылается на контекст пользовательского интерфейса. Термин будет true всякий раз, когда контекст пользовательского интерфейса активен и false в противном случае. |
HierSingleSelectionName:<pattern> | Термин будет true всякий раз, когда выбор в активной иерархии является одним элементом, а имя выбранного элемента соответствует регулярному выражению .NET, заданному шаблоном. |
User Параметры StoreQuery:<query> | "query" представляет полный путь в хранилище параметров пользователя, которое должно оцениваться ненулевым значением. Запрос разделен на коллекцию и свойствоName на последней косой черте. |
Config Параметры StoreQuery:<query> | "query" представляет полный путь в хранилище параметров конфигурации, которое должно оцениваться ненулевым значением. Запрос разделен на коллекцию и свойствоName на последней косой черте. |
ActiveProjectFlavor:<projectTypeGuid> | Термин будет true всякий раз, когда выбранный в данный момент проект вкусен (агрегирован) и имеет вкус, соответствующий заданному идентификатору GUID типа проекта. |
ActiveEditorContentType:<contentType> | Термин будет true, если выбранный документ является текстовым редактором с заданным типом контента. Примечание. При переименовании выбранного документа этот термин не обновляется до закрытия и повторного открытия файла. |
ActiveProjectCapability:<Expression> | Термин true, если активные возможности проекта соответствуют предоставленному выражению. Выражение может быть таким, как VB | Csharp. |
SolutionHasProjectCapability:<Expression> | Как и выше, но термин имеет значение true, если решение имеет любой загруженный проект, соответствующий выражению. |
SolutionHasProjectFlavor:<projectTypeGuid> | Термин будет true всякий раз, когда решение имеет проект с ароматизированным (агрегированным) и имеет вкус, соответствующий заданному идентификатору GUID типа проекта. |
ProjectAddedItem:<pattern> | Термин true, если файл, соответствующий шаблону, добавляется в проект в открываемом решении. |
ActiveProjectOutputType:<outputType> | Термин true, если тип вывода для активного проекта совпадает точно. OutputType может быть целым числом или типом __VSPROJOUTPUTTYPE . |
ActiveProjectBuildProperty:<buildProperty>=<regex> | Термин true, если активный проект имеет указанное свойство сборки и значение свойства соответствует указанному фильтру регулярных выражений. Дополнительные сведения о свойствах сборки см. в разделе "Сохранение данных в файлах проекта MSBuild". |
SolutionHasProjectBuildProperty:<buildProperty>=<regex> | Термин true, если решение имеет загруженный проект с указанным свойством сборки и значением свойства соответствует предоставленному фильтру regex. |
Совместимость с расширением кросс-версии
Контексты пользовательского интерфейса на основе правил — это новая функция в Visual Studio 2015 и не будет перенесена на более ранние версии. При переносе на более ранние версии возникает проблема с расширениями и пакетами, предназначенными для нескольких версий Visual Studio. Эти версии должны быть автоматически загружены в Visual Studio 2013 и более ранних версий, но могут воспользоваться контекстами пользовательского интерфейса на основе правил, чтобы предотвратить автоматическую загрузку в Visual Studio 2015.
Для поддержки таких пакетов записи AutoLoadPackages в реестре теперь могут предоставить флаг в поле значения, чтобы указать, что запись должна быть пропущена в Visual Studio 2015 и более поздних версиях. Это можно сделать, добавив параметр флагов в PackageAutoLoadFlags. VSPackages теперь может добавить параметр SkipWhenUIContextRulesActive к их ProvideAutoLoadAttribute атрибуту, чтобы указать, что запись должна игнорироваться в Visual Studio 2015 и выше.
Расширяемые правила контекста пользовательского интерфейса
Иногда пакеты не могут использовать статические правила контекста пользовательского интерфейса. Например, предположим, что у вас есть пакет, поддерживающий расширяемость, так что состояние команды основано на типах редакторов, поддерживаемых импортированными поставщиками MEF. Эта команда включена, если есть расширение, поддерживающее текущий тип редактирования. В таких случаях сам пакет не может использовать правило контекста статического пользовательского интерфейса, так как термины изменятся в зависимости от того, какие расширения MEF доступны.
Для поддержки таких пакетов контексты пользовательского интерфейса на основе правил поддерживают жестко закодированное выражение "*", указывающее, что все термины ниже будут присоединены к OR. Это позволяет главному пакету определить известный контекст пользовательского интерфейса на основе правил и связать его состояние команды с этим контекстом. После этого любой модуль MEF, предназначенный для главного пакета, может добавить его термины для редакторов, которые он поддерживает, не влияя на другие термины или основное выражение.
В документации конструктора ProvideExtensibleUIContextRuleAttribute показан синтаксис для расширяемых правил контекста пользовательского интерфейса.