針對 Visual Studio 擴充功能使用規則型 UI 內容
Visual Studio 允許在啟用特定已知 UIContext 時載入 VSPackage。 不過,這些 UI 內容不會精細微調,這讓擴充功能作者別無選擇,而是挑選可在真正想要 VSPackage 載入的點之前啟動的可用 UI 內容。 如需已知 UI 內容的清單,請參閱 KnownUIContexts。
載入套件可能會對效能造成影響,而且比實際需求更快載入套件並不是最佳做法。 Visual Studio 2015 引進了規則型 UI 內容概念,這個機制可讓擴充功能作者定義啟用 UI 內容並載入相關聯的 VSPackage 的精確條件。
規則型 UI 內容
「規則」是由新的 UI 內容 (GUID) 和布林值運算式所組成,可參考一或多個「詞彙」與邏輯「and」、「or」、「not」作業結合。 「詞彙」會在執行階段動態評估,每當任何詞彙變更時,就會重新評估運算式。 當運算式評估為 true 時,會啟動相關聯的 UI 內容。 否則,UI 內容會取消啟用。
規則型 UI 內容可以透過各種方式使用:
指定命令和工具視窗的可見性條件限制。 您可以隱藏命令/工具視窗,直到符合 UI 內容規則為止。
做為自動載入條件限制:只有在符合規則時才自動載入套件。
做為延遲的工作:延遲載入,直到指定的時間間隔通過,且規則仍符合。
任何 Visual Studio 擴充功能都可以使用機制。
建立規則型 UI 內容
假設您有一個名為 TestPackage 的副檔名,其提供功能表命令,僅適用於副檔名為 .config 的檔案。 在 VS2015 之前,最佳選項是在啟動 SolutionExistsAndFullyLoadedContext UI 內容時載入 TestPackage。 以這種方式載入 TestPackage 並不有效,因為載入的解決方案甚至可能不包含 .config 檔案。 這些步驟說明只有在選取副檔名為 .config 的檔案時,才能使用規則型 UI 內容來啟動 UI 內容,並在啟動該 UI 內容時載入 TestPackage。
定義新的 UIContext GUID,並將其新增至 VSPackage 類別 ProvideAutoLoadAttribute 和 ProvideUIContextRuleAttribute。
例如,假設要新增新的 UIContext「UIContextGuid」。 建立的 GUID (您可以按一下Tools>[建立 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$" })]
這些中繼資料會定義新的 UIContext GUID (8B40D5E2-5626-42AE-99EF-3DD1EFF46E7B) 和參考單一詞彙「DotConfig」的運算式。 每當使用中階層中的目前選取項目的名稱符合規則運算式模式「\.config$」時,「DotConfig」詞彙就會評估為 true (結尾為 .config)。 [預設值] 值會定義適用於偵錯之規則的選用名稱。
屬性的值會新增至建置期間產生的 pkgdef 之後。
在 TestPackage 命令的 VSCT 檔案中,將「DynamicVisibility」旗標新增至適當的命令:
<CommandFlag>DynamicVisibility</CommandFlag>
在 VSCT 的 VisibilityConstraints 區段中,將適當的命令繫結至 #1 中定義的新 UIContext GUID:
<VisibilityConstraints> <VisibilityItem guid="guidTestPackageCmdSet" id="TestId" context="UIContextGuid"/> </VisibilityConstraints>
在 [符號] 區段中,新增 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」,是指其他已知的 UI 內容 (由其 GUID)。 第三個詞彙 「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 內容為使用中且為 false 時,詞彙就會是 true。 |
HierSingleSelectionName:<pattern> | 每當使用中階層中的選取項目是單一項目,且選取項目的名稱符合「pattern」所提供的 .NET 規則運算式時,詞彙就會是 true。 |
UserSettingsStoreQuery:<query> | 「query」代表使用者設定存放區的完整路徑,必須評估為非零值。 查詢會分割成最後一個斜線的「collection」和「propertyName」。 |
ConfigSettingsStoreQuery:<query> | 「query」代表組態設定存放區的完整路徑,必須評估為非零值。 查詢會分割成最後一個斜線的「collection」和「propertyName」。 |
ActiveProjectFlavor:<projectTypeGuid> | 每當目前選取的專案為「已匯總」且具有符合指定專案類型 GUID 的類別時,詞彙就會是 true。 |
ActiveEditorContentType:<contentType> | 當選取的文件是具有指定內容類型的文字編輯器時,詞彙會是 true。 附註:當選取的文件重新命名時,此詞彙不會重新整理,直到檔案關閉並重新開啟為止。 |
ActiveProjectCapability:<Expression> | 當使用中的專案功能符合提供的運算式時,詞彙為 true。 運算式可以是類似 VB 的運算式 | CSharp。 |
SolutionHasProjectCapability:<Expression> | 與上述類似,但當解決方案有任何與陳述式相符的已載入專案時,詞彙為 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 來完成。 VSPackages 現在可以將 SkipWhenUIContextRulesActive 選項新增至其 ProvideAutoLoadAttribute 屬性,以指出應該在 Visual Studio 2015 和更新版本中略過。
可延伸 UI 內容規則
有時候,套件無法使用靜態 UI 內容規則。 例如,假設您有一個套件支援擴充性,因此命令狀態是以匯入的 MEF 提供者所支援的編輯器類型為基礎。 如果有支援目前編輯類型的擴充功能,則會啟用命令。 在這種情況下,套件本身無法使用靜態 UI 內容規則,因為詞彙會根據可用的 MEF 擴充功能而變更。
為了支援這類套件,規則型 UI 內容支援硬式編碼運算式 「*」,指出下列所有詞彙都會與 OR 聯結。 這可讓主要套件定義規則型已知 UI 內容,並將其命令狀態繫結至此內容。 之後,任何以主要套件為目標的 MEF 擴充功能都可以為它支援的編輯器新增其詞彙,而不會影響其他詞彙或主要運算式。
建構函式 ProvideExtensibleUIContextRuleAttribute 文件會顯示可延伸 UI 內容規則的語法。