WPF 設計工具擴充性架構
更新:2007 年 11 月
Windows Presentation Foundation (WPF) Designer for Visual Studio 是 WPF 複合控制項 (Composite Control) 的視覺化編輯環境,WPF 複合控制項是由 UserControl 型別所實作的。WPF 設計工具的設計概念為一套可擴充的架構,您可以擴充這個架構,豐富個人的設計體驗。
您可以擴充 WPF 設計工具物件模型 (Object Model),大幅自訂 WPF 內容的設計階段外觀和行為。例如,可以透過下列方式來擴充 WPF 設計工具:
使用進階圖形自訂移動及調整圖像 (Glyph) 大小的功能。
新增圖像至設計介面,使選取的控制項在滑鼠移動時出現傾斜的效果。
修改控制項在不同工具中的設計階段外觀和行為。
WPF 設計工具架構支援 WPF 完整的表現功能,因此可以營造許多以前無法實現的視覺化設計效果。
WPF 設計工具物件模型
WPF 設計工具屬於模組化的物件模型,這表示在擴充設計階段時,只會擴充您的功能所需要的項目,因此您不需要撰寫大量的支援程式碼來啟用自訂設計功能。
這個物件模型包含下表說明的五個功能單元。
功能單元 |
說明 |
---|---|
編輯模型 |
設計工具中物件的程式設計介面。 |
功能提供者 |
設計工具架構中的主要擴充點。 |
編輯內容 |
設計工具狀態的集中存放區。 |
工具 |
用於處理使用者輸入的工具。 |
中繼資料存放區 |
包含控制項之執行階段行為的存放區,這個位置可以具體區分設計工具的邏輯和執行階段的邏輯。 |
下圖顯示 WPF 設計工具物件模型。
注意事項: |
---|
WPF 設計工具支援完整擴充性架構。Expression Blend 只支援屬性編輯器、中繼資料載入和授權。Blend 不支援功能表動作和裝飾項。 |
編輯模型
設計環境是透過一個稱為編輯模型的程式設計介面,操作執行階段的控制項。這個編輯模型包含三個功能子單元:模型、擷取該模型的公用包裝函式,以及代表該模型之使用者介面 (UI) 的檢視。
設計環境使用 ModelItem 型別與基礎模型通訊。所有的變更都是針對 ModelItem 包裝函式進行,然後再由包裝函式影響基礎模型,如此便可讓模型保持簡單。ModelItem 包裝函式會處理複雜的設計工具功能,例如交易支援、復原追蹤和變更通知等。
ModelService 類別提供編輯模型和全域事件通知的進入點 (Entry Point)。
ViewService 類別會將視覺化表示對應至基礎模型項目。
這兩項服務都是設計工具正常運作不可或缺的要件。DesignerView 類別 (負責處理使用者輸入,並將輸入路由至命令) 需要這兩項服務,才能將使用者輸入正確對應回模型。
功能提供者
您可以使用 FeatureProvider 或 FeatureConnector<FeatureProviderType> 類別,擴充型別的設計階段行為。FeatureConnector<FeatureProviderType> 類別負責管理 FeatureProvider 物件的清單。
FeatureProvider 類別提供最基本的擴充點。功能提供者屬於輕量型的功能或是增益集,通常不需要設計環境的太多資源,而且都是在指定的內容中建立及部署。功能提供者可用來新增 UI 位元至設計介面,或是修改某些基本行為。例如,功能提供者可以加入更多的抓取控點,或是提供新的滑鼠拖曳行為類型。
若要達到最深的擴充性層級,請從 FeatureConnector<FeatureProviderType> 類別衍生。這個類別會公開服務提供者,而衍生的功能連接器類別可以透過這個服務提供者處理事件,並要求及發佈服務。例如,您可以實作功能連接器,以提供選取範圍 UI,或物件特定序列化 (Serialization).
一般而言,實作功能可擴充現有的概念,而實作功能連接器則可提供新的概念。如需詳細資訊,請參閱功能提供者和功能連接器。
編輯內容
執行中的設計工具會累積相當可觀的狀態資訊。例如,設計工具的狀態可能包括已選取哪些物件,或是按下滑鼠左鍵時所發生的行為。設計工具狀態儲存在集中的位置,如此您就可以在需要時找到這些狀態。EditingContext 類別代表設計工具狀態的這個集中儲存機制。
EditingContext 類別將狀態分成兩大類:資料和行為。資料會儲存成內容項目資料表,而行為則儲存成服務資料表。這兩個資料表都是使用型別式的索引鍵編製索引,也都可以列舉。
ContextItem 類別保留設計工具中狀態的單一部分。內容項目是不變的,但是新的內容項目可以取代現有的內容項目,以模擬可變動性。
服務可透過會傳回 ServiceManager 執行個體的 Services 屬性存取,而內容項目則可透過會傳回 ContextItemManager 執行個體的 Items 屬性來存取。
命令、工作和工具
WPF 設計工具工具架構包含命令、工作和工具。
「命令」(Command) 是代表某種行為的唯一識別項。例如,[剪下] 就是代表將目前的文字剪下並將它加入到 [剪貼簿] 的命令。實作 [剪下] 的程式碼會因為應用程式不同而改變,甚至在同一種應用程式內也會不同。例如,在 Word 文件中剪下文字和在同一份文件中剪下搜尋文字方塊中的文字,這兩個動作就分屬於不同的實作。但是不論哪一種實作,[剪下] 命令都是一樣的。
WPF 設計工具透過引進工具命令的概念,擴大了 WPF 的命令體系。工具命令會實作 ICommand 介面,與 RoutedCommand 類別十分類似。
「工作」(Task) 具有命令繫結集合,可以讓您加入路由命令。DesignerView 類別擁有程式碼,而該程式碼使用相同的路由策略做為工具命令,以尋找及執行工作中定義的路由命令。DesignerView 類別可啟用支援通用 WPF 命令 (例如 Copy) 的工作。
「工具」(Tool) 是負責處理使用者輸入的一種類別。所有的使用者輸入都是以一個或多個輸入事件的形式進入設計工具。這些輸入事件會傳遞至目前使用中的工具,再由該工具將輸入事件轉換成輸入繫結。如果傳回輸入繫結,系統就會執行繫結內的命令。
工具可以代表設計工具的全域模式。例如,如果使用者在設計介面上選取元件,就有可能出現該選取模式,因為目前使用中的工具會提供處理選取作業的輸入繫結和命令。當使用者建立控制項的新執行個體時,不同的工具就會開始作用,並提供一組繫結到相同輸入繫結的不同命令。
中繼資料存放區
在 WPF 設計工具架構中,定義控制項設計階段行為的中繼資料會納入一個稱為「中繼資料存放區」(Metadata Store) 的獨立組件。在 .NET Framework 3.5 中,中繼資料存放區會實作於程式碼架構的屬性 (Attribute) 表格中,其中包含一個參考設計工具程式碼的外部 XML 檔案以及一個設定檔。不同的工具可以搭配完全不同的設計工具實作,來提供不同的中繼資料存放區。如此便可區隔執行階段和設計階段行為,讓您直接修改設計工具,而不影響到控制項。如需詳細資訊,請參閱中繼資料存放區。
建立設計工具執行個體
下列步驟示範 WPF 設計工具環境如何具現化範例設計工具型別。這個虛構的範例顯示一個假設的設計工具如何在設計介面上選取單一控鈕控制項。
使用者叫用需要使用自訂設計工具的工具定義動作。
設計環境列舉功能對型別關聯的 XML 清單。
設計環境使用 TypeDescriptor 類別,將自訂中繼資料加入至這些型別。例如,GrabHandleProvider 可以與所有的 UIElement 型別產生關聯,包括衍生型別。
編輯處理站建立編輯存放區、內容和功能管理員,並填入編輯存放區。
WPF 設計工具列舉由編輯存放區公開的所有 UIElement 物件,並針對每個物件呼叫 InitializeFeatures 方法。
假設 Button 項目已在這個階層中宣告。
FeatureManager 在按鈕上搜尋 FeatureAttribute。FeatureManager 在 GrabHandleProvider 型別的按鈕上找到 FeatureAttribute。
FeatureManager 繼續搜尋 GrabHandleProvider 型別,並找到與其關聯的 FeatureConnectorAttribute。FeatureConnectorAttribute 指定 SelectionConnector。
FeatureManager 判斷這個主應用程式 (Host) 尚未存在。FeatureManager 建立 SelectionConnector,並將它加入使用中功能主應用程式的清單中。
SelectionConnector 物件開始監視設計介面是否變更選取範圍。SelectionConnector 物件也取得裝飾項層的參考。
使用者將選取範圍改成按鈕,而設計階段工具則引發選取範圍變更事件。
SelectionConnector 收到此通知,並建立與所選物件相關聯並以選取範圍為根據的所有 FeatureProvider 執行個體,包括 GrabHandleProvider 執行個體。
SelectionConnector 查詢 GrabHandleProvider 以找出裝飾項清單,並將它們加入至裝飾項層。抓取控點隨即出現在選取的按鈕四周。
WPF 設計工具組件
WPF 設計工具包含數個組件,而這些組件分屬於下列三種分類的其中一類:公用、私用和 Visual Studio 專用。
公用組件公開的類別可用來將設計階段邏輯加入至控制項。
私用和 Visual Studio 專用組件可定義 WPF 設計工具的功能集,以及這套工具與 Visual Studio 的互動。下表顯示 WPF 設計工具功能是如何部署的。
組件 |
公用 API |
說明 |
---|---|---|
Microsoft.VisualStudio.Xaml.dll |
否 |
Visual Studio SDK 整合邏輯。 |
Microsoft.Windows.Design.Host.dll |
是 |
用於裝載設計工具的公用 API (Visual Studio 專用)。 |
Microsoft.Windows.Design.Developer.dll |
否 |
WPF 設計工具 實作。只有公用 API 才是屬性表格。 |
Microsoft.Windows.Design.Core.dll |
是 |
透過服務與資料後擋板,以及中繼資料的操作,提供任何設計工具的基礎。這是 Expression Blend 支援的唯一組件。 |
Microsoft.Windows.Design.Extensibility.dll |
是 |
透過屬性提供擴充性模型。 |
Microsoft.Windows.Design.Interaction.dll |
是 |
提供使用者輸入和顯示類別。 |
Microsoft.Windows.Design.Markup.dll |
是 |
提供 Extensible Application Markup Language (XAML) 和文件模型機制。 |
注意事項: |
---|
組件代表功能界限,而非命名空間界限。您常常會發現跨越多個組件的命名空間。 |
WPF 設計工具和 Windows Form 設計工具架構
WPF 設計工具的架構和 Windows Form 設計工具架構的差異非常大,後者的特色是有 IComponent 介面和 System.ComponentModel 命名空間。如需詳細資訊,請參閱比較 Windows Form 設計工具架構與 WPF 設計工具架構。