Visual Studio 확장에 규칙 기반 UI 컨텍스트 사용
Visual Studio에서는 일부 잘 알려진 UIContext가 활성화되면 VSPackage를 로드할 수 있습니다. 그러나 이러한 UI 컨텍스트는 세분화되지 않으므로 확장 작성자는 VSPackage가 실제로 로드하기를 원하는 지점 이전에 활성화되는 사용 가능한 UI 컨텍스트를 선택할 수밖에 없습니다. 잘 알려진 UI 컨텍스트의 목록은 KnownUIContexts를 참조하세요.
패키지를 로드하면 성능에 영향을 줄 수 있으며 필요한 것보다 빨리 로드하는 것은 모범 사례가 아닙니다. Visual Studio 2015에서는 확장 작성자가 UI 컨텍스트가 활성화되고 관련 VSPackage가 로드되는 정확한 조건을 정의할 수 있는 메커니즘인 규칙 기반 UI 컨텍스트의 개념을 도입했습니다.
규칙 기반 UI 컨텍스트
"규칙"은 논리 "and", "or", "not" 작업과 결합된 하나 이상의 "항"을 참조하는 새 UI 컨텍스트(GUID) 및 부울 식으로 구성됩니다. "항"은 런타임에 동적으로 계산되며 해당 항이 변경될 때마다 식이 다시 계산됩니다. 식이 true로 계산되면 연결된 UI 컨텍스트가 활성화됩니다. 그렇지 않으면 UI 컨텍스트가 활성화되지 않습니다.
규칙 기반 UI 컨텍스트는 다음과 같은 다양한 방법으로 사용할 수 있습니다.
명령 및 도구 창에 대한 표시 유형 제약 조건을 지정합니다. UI 컨텍스트 규칙이 충족될 때까지 명령/도구 창을 숨길 수 있습니다.
자동 로드 제약 조건으로: 규칙이 충족되는 경우에만 패키지를 자동 로드합니다.
지연된 작업으로: 지정된 시간이 경과하고 규칙이 여전히 충족될 때까지 로드를 지연합니다.
이 메커니즘은 Visual Studio 확장에서 사용할 수 있습니다.
규칙 기반 UI 컨텍스트 만들기
확장명이 .config 파일에만 적용되는 메뉴 명령을 제공하는 TestPackage라는 확장이 있다고 가정해 보겠습니다. VS2015 이전에는 SolutionExistsAndFullyLoadedContext UI 컨텍스트가 활성화되었을 때 TestPackage를 로드하는 것이 가장 좋았습니다. 로드된 솔루션에 .config 파일이 포함되지 않을 수 있으므로 이러한 방식으로 TestPackage를 로드하는 것은 효율적이지 않습니다. 다음 단계에서는 규칙 기반 UI 컨텍스트를 사용하여 확장명이 .config인 파일을 선택한 경우에만 UI 컨텍스트를 활성화하고 해당 UI 컨텍스트가 활성화될 때 TestPackage를 로드하는 방법을 보여 줍니다.
새 UIContext GUID를 정의하여 VSPackage 클래스 ProvideAutoLoadAttribute 및 ProvideUIContextRuleAttribute에 추가합니다.
예를 들어 새 UIContext "UIContextGuid"를 추가해야 한다고 가정해 보겠습니다. 만든 GUID는 "8B40D5E2-5626-42AE-99EF-3DD1EFF46E7B"입니다(GUID는 도구>GUID 만들기를 클릭하여 만들 수 있음). 그런 다음 패키지 클래스 내에 다음 선언을 추가합니다.
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$" })]
이러한 메타데이터는 새 UIContext GUID(8B40D5E2-5626-42AE-99EF-3DD1EFF46E7B)와 단일 항 "DotConfig"를 참조하는 식을 정의합니다. "DotConfig" 항은 활성 계층 구조의 현재 선택 영역에 정규식 패턴 "\.config$"(.config로 끝남)와 일치하는 이름이 있을 때마다 true로 계산됩니다. 이 (기본)값은 디버깅에 유용한 규칙의 선택적 이름을 정의합니다.
이 특성의 값은 나중에 빌드 시간 동안 생성된 pkgdef에 추가됩니다.
TestPackage의 명령에 대한 VSCT 파일에서 적절한 명령에 "DynamicVisibility" 플래그를 추가합니다.
<CommandFlag>DynamicVisibility</CommandFlag>
VSCT의 VisibilityConstraints 섹션에서 적절한 명령을 #1에 정의된 새 UIContext GUID에 연결합니다.
<VisibilityConstraints> <VisibilityItem guid="guidTestPackageCmdSet" id="TestId" context="UIContextGuid"/> </VisibilityConstraints>
Symbols 섹션에서 UIContext의 정의를 추가합니다.
<GuidSymbol name="UIContextGuid" value="{8B40D5E2-5626-42AE-99EF-3DD1EFF46E7B}" />
이제 솔루션 탐색기에서 선택한 항목이 .config 파일이고 해당 명령 중 하나를 선택할 때까지 패키지가 로드되지 않는 경우에만 *.config 파일에 대한 바로 가기 메뉴 명령이 표시됩니다.
다음으로 디버거를 사용하여 예상한 경우에만 패키지가 로드되는지 확인합니다. TestPackage를 디버그하려면
Initialize 메서드에서 중단점을 설정합니다.
TestPackage를 빌드하고 디버깅을 시작합니다.
프로젝트를 만들거나 엽니다.
.config 이외의 확장명을 가진 파일을 선택합니다. 중단점이 적중하면 안 됩니다.
App.Config 파일을 선택합니다.
TestPackage가 로드되고 중단점에서 중지됩니다.
UI 컨텍스트에 대한 규칙 추가
UI 컨텍스트 규칙은 부울 식이므로 UI 컨텍스트에 대해 더 제한적인 규칙을 추가할 수 있습니다. 예를 들어 위의 UI 컨텍스트에서 프로젝트가 있는 솔루션이 로드될 때만 규칙이 적용되도록 지정할 수 있습니다. 이렇게 하면 .config 파일을 프로젝트의 일부가 아닌 독립 실행형 파일로 열면 명령이 표시되지 않습니다.
[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로 다른 잘 알려진 UI 컨텍스트를 참조합니다. 세 번째 항인 "DotConfig"는 이 문서의 앞부분에서 정의한 규칙 기반 UI 컨텍스트입니다.
지연된 활성화
규칙에는 선택적으로 "지연"이 포함될 수 있습니다. 지연은 밀리초 단위로 지정됩니다. 포함된 경우 지연으로 인해 규칙의 UI 컨텍스트 활성화 또는 비활성화가 해당 시간만큼 지연됩니다. 지연 간격 전에 규칙이 다시 변경되면 아무 일도 발생하지 않습니다. 이 메커니즘은 초기화 단계를 "분산"하는 데 사용할 수 있습니다. 특히 타이머에 의존하거나 유휴 알림에 등록하지 않고 일회성 초기화를 수행할 수 있습니다.
예를 들어 테스트 부하 규칙이 100밀리초의 지연 시간을 가지도록 지정할 수 있습니다.
[ProvideAutoLoad(TestPackage.UIContextGuid)]
[ProvideUIContextRule(TestPackage.UIContextGuid,
name: "Test auto load",
expression: "DotConfig",
termNames: new[] { "DotConfig" },
termValues: new[] { "HierSingleSelectionName:.config$" },
delay: 100)]
항 유형
지원되는 다양한 유형의 항은 다음과 같습니다.
용어 | 설명 |
---|---|
{nnnnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnn} | GUID는 UI 컨텍스트를 참조합니다. 이 항은 UI 컨텍스트가 활성 상태인 경우 항상 true이고 그렇지 않으면 false입니다. |
HierSingleSelectionName:<pattern> | 이 항은 현재 계층 구조의 선택 영역이 단일 항목이고 선택한 항목의 이름이 "패턴"에 의해 지정된 .NET 정규식과 일치하는 경우 항상 true입니다. |
UserSettingsStoreQuery:<query> | "쿼리"는 0이 아닌 값으로 계산되어야 하는 사용자 설정 저장소의 전체 경로를 나타냅니다. 쿼리는 마지막 슬래시에서 "컬렉션" 및 "propertyName"으로 분할됩니다. |
ConfigSettingsStoreQuery:<query> | "쿼리"는 0이 아닌 값으로 계산되어야 하는 config 설정 저장소의 전체 경로를 나타냅니다. 쿼리는 마지막 슬래시에서 "컬렉션" 및 "propertyName"으로 분할됩니다. |
ActiveProjectFlavor:<projectTypeGuid> | 이 항은 현재 선택한 프로젝트가 버전이 지정(집계)되고 지정된 프로젝트 형식 GUID와 일치하는 버전이 있는 경우 항상 true입니다. |
ActiveEditorContentType:<contentType> | 이 항은 선택한 문서가 지정된 콘텐츠 형식의 텍스트 편집기인 경우 true입니다. 참고: 선택한 문서의 이름을 바꾸면 파일을 닫았다가 다시 열 때까지 이 항이 새로 고쳐지지 않습니다. |
ActiveProjectCapability:<식> | 이 항은 활성 프로젝트 기능이 제공된 식과 일치하는 경우 true입니다. 식은 VB | CSharp와 같을 수 있습니다. |
SolutionHasProjectCapability:<식> | 이 항은 위와 비슷하지만 솔루션에 식과 일치하는 프로젝트가 로드되어 있는 경우 true입니다. |
SolutionHasProjectFlavor:<projectTypeGuid> | 이 항은 솔루션에 버전이 지정(집계)된 프로젝트가 있고 지정된 프로젝트 형식 GUID와 일치하는 버전이 있는 경우 항상 true입니다. |
ProjectAddedItem:<pattern> | 이 항은 열린 솔루션에서 프로젝트에 "패턴"과 일치하는 파일이 추가되는 경우 true입니다. |
ActiveProjectOutputType:<outputType> | 이 항은 활성 프로젝트의 출력 형식이 정확히 일치하는 경우 true입니다. outputType은 정수 또는 __VSPROJOUTPUTTYPE 형식일 수 있습니다. |
ActiveProjectBuildProperty:<buildProperty>=<regex> | 이 항은 활성 프로젝트에 지정된 빌드 속성이 있고 속성 값이 제공된 regex 필터와 일치하는 경우 true입니다. 빌드 속성에 대한 자세한 내용은 MSBuild 프로젝트 파일에서 데이터 유지를 참조하세요. |
SolutionHasProjectBuildProperty:<buildProperty>=<regex> | 이 항은 솔루션에 지정된 빌드 속성을 가진 프로젝트가 로드되어 있고 속성 값이 제공된 regex 필터와 일치하는 경우 true입니다. |
버전 간 확장과의 호환성
규칙 기반 UI 컨텍스트는 Visual Studio 2015의 새로운 기능이며 이전 버전으로 이식되지 않습니다. 이전 버전으로 이식되지 않으므로 여러 버전의 Visual Studio를 대상으로 하는 확장/패키지에서 문제가 발생합니다. 이러한 버전은 Visual Studio 2013 및 이전 버전에서 자동으로 로드되어야 하지만, 규칙 기반 UI 컨텍스트를 활용하여 Visual Studio 2015에서 자동으로 로드되지 않도록 할 수 있습니다.
이러한 패키지를 지원하기 위해 이제 레지스트리의 AutoLoadPackages 항목은 해당 값 필드에 플래그를 제공하여 Visual Studio 2015 이상에서 항목을 건너뛰어야 함을 나타낼 수 있습니다. 이 작업은 PackageAutoLoadFlags에 플래그 옵션을 추가하여 수행할 수 있습니다. VSPackage는 이제 해당 ProvideAutoLoadAttribute 특성에 SkipWhenUIContextRulesActive 옵션을 추가하여 Visual Studio 2015 이상에서 항목을 무시해야 함을 나타낼 수 있습니다.
확장 가능한 UI 컨텍스트 규칙
경우에 따라 패키지가 정적 UI 컨텍스트 규칙을 사용할 수 없을 수 있습니다. 예를 들어 명령 상태가 가져온 MEF 공급자에서 지원하는 편집기 형식을 기반으로 하는 확장성을 지원하는 패키지가 있다고 가정해 보겠습니다. 현재 편집 형식을 지원하는 확장이 있는 경우 이 명령이 사용됩니다. 이러한 경우 사용 가능한 MEF 확장에 따라 항이 변경되므로 패키지 자체는 정적 UI 컨텍스트 규칙을 사용할 수 없습니다.
이러한 패키지를 지원하기 위해 규칙 기반 UI 컨텍스트는 이하의 모든 항이 OR과 조인됨을 나타내는 하드 코드된 식 "*"을 지원합니다. 이렇게 하면 마스터 패키지가 알려진 규칙 기반 UI 컨텍스트를 정의하고 해당 명령 상태를 이 컨텍스트에 연결할 수 있습니다. 그 이후에는 마스터 패키지의 대상이 되는 MEF 확장이 다른 항 또는 마스터 식에 영향을 주지 않고 지원하는 편집기에 대한 항을 추가할 수 있습니다.
ProvideExtensibleUIContextRuleAttribute 생성자 설명서에는 확장 가능한 UI 컨텍스트 규칙에 대한 구문이 나와 있습니다.