共用方式為


WPF 增益集概觀

.NET Framework 包含增益集模型,開發人員可用來建立支援增益集擴充性的應用程式。 此增益集模型可讓您建立增益集,整合並擴充應用程式的功能。 在某些情況下,應用程式也需要顯示增益集所提供的使用者介面。本主題說明 WPF 如何增強 .NET Framework 增益集模型,以啟用這些案例、其背後的架構、其優點及其限制。

必要條件

需要熟悉 .NET Framework 增益集模型。 如需詳細資訊,請參閱增益集和擴充性

增益集概觀

為避免新功能包含複雜的應用程式重新編譯和重新部署,應用程式會實作擴充性機制,讓開發人員 (第一方和第三方) 建立整合它們的其他應用程式。 支援此擴充性類型最常見的方式是使用增益集 (也稱為「附加元件」和「外掛程式」)。 公開增益集擴充性的真實世界應用程式範例包括︰

  • Internet Explorer 附加元件。

  • Windows Media Player 外掛程式。

  • Visual Studio 增益集。

例如,Windows Media Player 增益集模型讓協力廠商開發人員實作以各種方式擴充 Windows Media Player 的「外掛程式」,包括建立適用於 Windows Media Player 原本不支援之媒體格式的解碼器和編碼器 (例如 DVD、MP3)、音訊效果和面板。 每個增益集模型都是建置來公開對應用程式的獨特功能,雖然有幾個實體和行為通用所有的增益集模型。

一般增益集擴充性解決方案的三個主要實體是「合約」、「增益集」和「主應用程式」。 合約定義增益集與主應用程式整合的兩種方式︰

  • 增益集整合主應用程式所實作的功能。

  • 主應用程式公開要整合的增益集功能。

為能使用增益集,主應用程式需要在執行階段找到並載入它們。 因此,支援增益集的應用程式有下列額外的責任︰

  • 探索︰尋找遵守主應用程式所支援合約的增益集。

  • 啟用︰載入、執行及建立與增益集的通訊。

  • 隔離︰使用應用程式定義域或處理程序來建立隔離界限,保護應用程式不受增益集的潛在安全性和執行問題影響。

  • 通訊︰透過呼叫方法及傳送資料,讓增益集及主應用程式跨越隔離界限互相通訊。

  • 存留期管理︰以簡潔、可預測的方式載入和卸載應用程式定義域和處理程序 (請參閱應用程式定義域)。

  • 版本控制︰確保建立任一新版本時,主應用程式和增益集仍可通訊。

最後,開發強固的增益集模型是重要的工作。 基於這個理由,.NET Framework 提供建置增益集模型的基礎結構。

注意

如需增益集的詳細資訊,請參閱增益集和擴充性

.NET Framework 增益集模型概觀

命名空間中找到的 System.AddIn .NET Framework 增益集模型包含一組類型,其設計目的是簡化增益集擴充性的開發。 .NET Framework 增益集模型的基本單位是 合約 ,它會定義主應用程式和增益集如何彼此通訊。 合約會向使用合約主應用程式特定「檢視」的主應用程式公開。 同樣地,合約的增益集專用「檢視」也會向增益集公開。 「配接器」用以讓主應用程式和增益集在其各自的合約檢視間進行通訊。 合約、檢視和配接器稱為區段,一組相關的區段構成「管線」。 管線是 .NET Framework 增益集模型支援探索、啟用、安全性隔離、執行隔離(同時使用應用程式域和進程)、通訊、存留期管理和版本控制的基礎。

這項支援的要點是讓開發人員建置增益集,整合主應用程式的功能。 不過,某些案例需要主應用程式顯示增益集所提供的使用者介面。因為 .NET Framework 中的每個簡報技術都有自己的模型來實作使用者介面,因此 .NET Framework 增益集模型不支援任何特定的呈現技術。 相反地,WPF 會使用增益集的 UI 支援來擴充 .NET Framework 增益集模型。

WPF 增益集

WPF 與 .NET Framework 增益集模型搭配使用,可讓您解決各種不同的案例,這些案例需要主應用程式從增益集顯示使用者介面。特別是,WPF 會使用下列兩種程式設計模型來解決這些案例:

  1. 增益集傳回 UI。 增益集會透過方法呼叫將 UI 傳回至主應用程式,如合約所定義。 此案例用於下列情況︰

    • 增益集傳回的 UI 外觀取決於只存在於執行時間的資料或條件,例如動態產生的報表。

    • 增益集所提供的服務 UI 與主應用程式的 UI 不同,這些應用程式可以使用增益集。

    • 增益集主要會執行主應用程式的服務,並使用 UI 向主應用程式報告狀態。

  2. 增益集為 UI。 增益集是一個 UI,如合約所定義。 此案例用於下列情況︰

    • 增益集不提供顯示以外的服務,例如廣告。

    • 增益集所提供的服務 UI 適用于所有可使用該增益集的主應用程式,例如計算機或色彩選擇器。

這些案例要求可以在主應用程式與增益集應用程式域之間傳遞 UI 物件。 由於 .NET Framework 增益集模型依賴遠端功能在應用程式域之間通訊,因此在應用程式域之間傳遞的物件必須可遠端處理。

可在遠端處理的物件是執行下列一或多個工作的類別執行個體︰

注意

如需建立可遠端 .NET Framework 物件的詳細資訊,請參閱 讓物件成為遠端

WPF UI 類型無法遠端處理。 為了解決此問題,WPF 會擴充 .NET Framework 增益集模型,讓增益集建立的 WPF UI 可從主應用程式顯示。 這個支援是由 WPF 由兩種類型提供: INativeHandleContract 介面和 類別所實作的 FrameworkElementAdapters 兩個靜態方法: ContractToViewAdapterViewToContractAdapter 。 概括而言,這些類型和方法的使用方式如下︰

  1. WPF 要求增益集所提供的使用者介面是直接或間接衍生自 FrameworkElement 的類別,例如圖形、控制項、使用者控制項、版面配置面板和頁面。

  2. 無論合約宣告將在增益集與主應用程式之間傳遞 UI,它都必須宣告為 INativeHandleContract (不是 ), FrameworkElementINativeHandleContract 是可跨隔離界限傳遞之增益集 UI 的可遠端標記法。

  3. 從增益集的應用程式域傳遞之前,會 FrameworkElement 藉由呼叫 ViewToContractAdapter 封裝為 INativeHandleContract

  4. 傳遞至主應用程式的應用程式域之後, INativeHandleContract 必須藉由呼叫 ContractToViewAdapter 重新封裝為 FrameworkElement

ContractToViewAdapterViewToContractAdapter 的使用 INativeHandleContract 方式取決於特定案例。 下列各節提供每個程式設計模型的詳細資料。

增益集傳回使用者介面

若要讓增益集將 UI 傳回主應用程式,需要下列專案:

  1. 必須建立主應用程式、增益集和管線,如 .NET Framework 增益集和擴充性 檔所述。

  2. 合約必須實 IContract 作 ,而且,若要傳回 UI,合約必須宣告具有 型 INativeHandleContract 別傳回值的方法。

  3. 增益集與主應用程式之間傳遞的 UI 必須直接或間接衍生自 FrameworkElement

  4. 增益集傳回的 UI 必須在跨越隔離界限之前,從 FrameworkElementINativeHandleContract 轉換成 。

  5. 傳回的 UI 必須在越過隔離界限之後,從 INativeHandleContractFrameworkElement 轉換為 。

  6. 主應用程式會顯示傳回的 FrameworkElement

如需示範如何實作傳回 UI 的增益集的範例,請參閱 建立會傳回 UI 的增益集。

增益集是使用者介面

當增益集是 UI 時,需要下列專案:

  1. 必須建立主應用程式、增益集和管線,如 .NET Framework 增益集和擴充性 檔所述。

  2. 增益集的合約介面必須實 INativeHandleContract 作 。

  3. 傳遞至主應用程式的增益集必須直接或間接衍生自 FrameworkElement

  4. 增益集必須從 FrameworkElementINativeHandleContract 轉換為 ,才能跨越隔離界限。

  5. 增益集必須在跨越隔離界限之後,從 INativeHandleContractFrameworkElement 轉換為 。

  6. 主應用程式會顯示傳回的 FrameworkElement

如需示範如何實作 UI 增益集的範例,請參閱 建立 UI 的 增益集。

從增益集傳回多個 UI

增益集通常會提供多個使用者介面,以供主應用程式顯示。 例如,假設增益集是 UI,也會提供狀態資訊給主應用程式,也可以做為 UI。 像這樣的增益集的實作方法是,使用增益集傳回使用者介面增益集是使用者介面模型這兩種技術的組合。

增益集和 XAML 瀏覽器應用程式

在到目前為止的範例中,主應用程式一直是已安裝的獨立應用程式。 但 XAML 瀏覽器應用程式 (XBAP) 也可以裝載增益集,儘管有下列額外的建置和實作需求:

  • XBAP 應用程式資訊清單必須特別設定為將管線(資料夾和元件)和增益集元件下載至用戶端電腦上 ClickOnce 應用程式快取,與 XBAP 位於相同的資料夾中。

  • 探索和載入增益集的 XBAP 程式碼必須使用 XBAP 的 ClickOnce 應用程式快取作為管線和增益集位置。

  • 如果增益集參考位於源月臺的鬆散檔案,XBAP 必須將增益集載入至特殊安全性內容;由 XBAP 裝載時,增益集只能參考位於主應用程式來源網站的鬆散檔案。

下列各小節將詳細說明這些工作。

設定 ClickOnce 部署的管線和增益集

XBAP 會從 ClickOnce 部署快取中的安全資料夾下載並執行。 為了讓 XBAP 裝載增益集,管線和增益集元件也必須下載到安全資料夾。 為達到此目的,您需要設定應用程式資訊清單包含管線和增益集組件以供下載。 這在 Visual Studio 中最為容易完成,不過管線和增益集元件必須位於主機 XBAP 專案的根資料夾中,才能讓 Visual Studio 偵測管線元件。

因此,第一個步驟是藉由設定每個管線元件和增益集元件專案的組建輸出,將管線和增益集元件建置至 XBAP 專案的根目錄。 下表顯示管線元件專案和增益集元件專案的組建輸出路徑,這些專案與主機 XBAP 專案位於相同的方案和根資料夾中。

表 1:XBAP 裝載之管線組件的組建輸出路徑

管線組件專案 建置輸出路徑
合約 ..\HostXBAP\Contracts\
增益集檢視 ..\HostXBAP\AddInViews\
增益集端配接器 ..\HostXBAP\AddInSideAdapters\
主控件端配接器 ..\HostXBAP\HostSideAdapters\
增益集 ..\HostXBAP\AddIns\WPFAddIn1

下一個步驟是執行下列動作,將管線元件和增益集元件指定為 Visual Studio 中的 XBAPs 內容檔案:

  1. 以滑鼠右鍵按一下方案總管中每個管線資料夾,然後選擇 [加入至專案],在專案中包含管線和增益集組件。

  2. 從 [屬性] 視窗將每個管線組件和增益集組件的 [建置動作] 設定為 [內容]

最後一個步驟,是設定應用程式資訊清單包含管線組件檔和增益集組件檔以供下載。 這些檔案應該位於 XBAP 應用程式所佔用之 ClickOnce 快取中資料夾根目錄的資料夾。 您可以在 Visual Studio 中執行下列動作來達成設定:

  1. 以滑鼠右鍵按一下 XBAP 專案,按一下 [內容 ],按一下 [發佈 ],然後按一下 [應用程式檔] 按鈕。

  2. 在 [應用程式檔案] 對話方塊中,將每個管線和增益集 DLL 的 [發行狀態] 設成 [Include (Auto)] (包含 (自動)),並將每個管線和增益集 DLL 的 [下載群組] 設成 [(必要項)]

使用來自應用程式基底的管線和增益集

當管線和增益集設定為 ClickOnce 部署時,它們會下載到與 XBAP 相同的 ClickOnce 快取資料夾。 若要從 XBAP 使用管線和增益集,XBAP 程式碼必須從應用程式基底取得它們。 使用管線和增益集的 .NET Framework 增益集模型的各種類型和成員,為此案例提供特殊支援。 首先,列舉值會識別 ApplicationBase 路徑。 您使用此值與相關增益集成員的多載處理使用包含下列各項的管線︰

存取裝載的原始網站

為確保增益集能參考原始網站的檔案,必須使用相當於主應用程式的安全性隔離載入增益集。 列舉值會識別 AddInSecurityLevel.Host 此安全性層級,並在增益集啟動時傳遞至 Activate 方法。

WPF 增益集架構

在最高層級,如我們所見,WPF 可讓 .NET Framework 增益集使用 INativeHandleContractViewToContractAdapterContractToViewAdapter 實作使用者介面(直接或間接衍生自 FrameworkElement )。 結果是,主應用程式會從主應用程式中的 UI 傳回 FrameworkElement 所顯示的 。

針對簡單的 UI 增益集案例,這與開發人員需求一樣詳細。 對於更複雜的案例,特別是那些嘗試使用其他 WPF 服務,例如版面配置、資源和資料系結的案例,需要更詳細瞭解 WPF 如何透過 UI 支援擴充 .NET Framework 增益集模型,以瞭解其優點和限制。

基本上,WPF 不會將 UI 從增益集傳遞至主應用程式;相反地,WPF 會使用 WPF 互通性傳遞 UI 的 Win32 視窗控制碼。 因此,將增益集的 UI 傳遞至主應用程式時,會發生下列情況:

HwndHost 存在以顯示 WPF 使用者介面中視窗控制碼所識別的使用者介面。 如需詳細資訊,請參閱 WPF 和 Win32 互通

總而言之, INativeHandleContractViewToContractAdapterContractToViewAdapter 存在可讓 WPF UI 的視窗控制碼從增益集傳遞至主應用程式,其中會由 HwndHost 封裝並顯示主應用程式的 UI。

注意

因為主應用程式會取得 HwndHost ,所以主應用程式無法將 所 ContractToViewAdapter 傳回的物件轉換成增益集實作的類型(例如 , 。 UserControl

根據其本質, HwndHost 有一些限制會影響主應用程式如何使用它們。 不過,WPF 會 HwndHost 使用數個增益集案例的功能來擴充。 下文說明這些優點與限制。

WPF 增益集的優點

由於 WPF 增益集使用者介面是使用衍生自 HwndHost 的內部類別從主應用程式顯示,因此這些使用者介面受限於與 WPF UI 服務相關的功能 HwndHost ,例如版面配置、轉譯、資料系結、樣式、範本和資源。 不過,WPF 會使用包含下列其他功能來增強其內部 HwndHost 子類別:

  • 主應用程式的 UI 與增益集 UI 之間的索引標籤。 請注意,「增益集是 UI」程式設計模型需要增益集端配接器才能覆寫 QueryContract ,才能啟用索引標籤,無論是完全信任增益集還是部分信任。

  • 接受從主應用程式使用者介面顯示之增益集使用者介面的協助工具需求。

  • 讓 WPF 應用程式能夠在多個應用程式域案例中安全地執行。

  • 當增益集以安全性隔離執行時,防止對增益集 UI 視窗進行非法存取(也就是部分信任安全性沙箱)。 呼叫 ViewToContractAdapter 可確保此安全性:

    • 對於「增益集傳回 UI」程式設計模型,跨隔離界限傳遞增益集 UI 視窗控制碼的唯一方法是呼叫 ViewToContractAdapter

    • 針對「增益集是 UI」程式設計模型,在增益集端配接器上覆 QueryContract 寫和呼叫 (如上述範例所示)是必要的,如同從主機端配 QueryContract 接器呼叫 ViewToContractAdapter 增益集配接器的實作一樣。

  • 提供多個應用程式定義域執行保護。 由於應用程式定義域的限制,增益集應用程式定義域中擲回的未處理例外狀況會導致整個應用程式當機,即使有隔離界限。 不過,WPF 和 .NET Framework 增益集模型提供簡單的方法來解決此問題,並改善應用程式穩定性。 如果主應用程式是 WPF 應用程式,則顯示 UI 的 WPF 增益集會為應用程式域執行的執行緒建立 Dispatcher 。 您可以藉由處理 UnhandledException WPF 增益集 的 Dispatcher 事件,偵測應用程式域中發生的所有未處理的例外狀況。 您可以從 屬性取得 DispatcherCurrentDispatcher

WPF 增益集限制

除了 WPF 新增至 、 HwndHost 和 視窗控制碼所提供 HwndSource 之預設行為的優點之外,還有從主應用程式顯示之增益集使用者介面的限制:

  • 從主應用程式顯示的增益集使用者介面不會遵守主應用程式的裁剪行為。

  • 互通性案例中的「空間」概念也適用於增益集 (請參閱技術領域概觀)。

  • 主應用程式的 UI 服務,例如資源繼承、資料系結和命令,不會自動提供給增益集使用者介面。 若要向增益集提供這些服務,您需要更新管線。

  • 增益集 UI 無法旋轉、縮放、扭曲或其他受轉換影響(請參閱 轉換概觀 )。

  • 透過從 System.Drawing 命名空間繪製作業所轉譯的增益集使用者介面內的內容可以包含 Alpha 混合。 不過,增益集 UI 和包含它的主應用程式 UI 都必須是 100% 不透明;換句話說, Opacity 兩者上的 屬性都必須設定為 1。

  • AllowsTransparency如果主應用程式中包含增益集 UI 的視窗屬性設定為 true ,則增益集是看不見的。 即使增益集 UI 是 100% 不透明,也是如此(也就是說, Opacity 屬性的值為 1)。

  • 增益集 UI 必須出現在相同最上層視窗中其他 WPF 元素的頂端。

  • 增益集 UI 中沒有任何部分可以使用 來轉譯 VisualBrush 。 相反地,增益集可能會擷取所產生 UI 的快照集,以建立可使用合約所定義方法傳遞至主應用程式的點陣圖。

  • 無法在增益集 UI 中播放 MediaElement 媒體檔案。

  • 針對增益集 UI 產生的滑鼠事件不會由主應用程式接收或引發,而 IsMouseOver 主應用程式 UI 的 屬性具有 值 false

  • 當焦點在增益集 UI 中的控制項之間轉移時, GotFocus 主應用程式不會接收和引發 和 LostFocus 事件。

  • 主應用程式包含增益集 UI 的部分會在列印時顯示為白色。

  • 如果主應用程式繼續執行,則增益集 UI 所建立的所有發送器(請參閱) Dispatcher 都必須手動關閉,才能卸載擁有者增益集。 合約可以實作方法,讓主應用程式在卸載增益集之前發出訊號,藉此允許增益集 UI 關閉其發送器。

  • 如果增益集 UI 是 InkCanvas 或 包含 InkCanvas ,則無法卸載增益集。

效能最佳化

根據預設,使用多個應用程式域時,每個應用程式所需的各種 .NET Framework 元件都會載入該應用程式的網域。 如此一來,建立新應用程式定義域以及從其中啟動應用程式所需的時間,可能會影響效能。 不過,.NET Framework 可讓您減少開始時間,方法是指示應用程式在已載入時跨應用程式域共用元件。 您可以使用 屬性來執行此動作 LoaderOptimizationAttribute ,此屬性必須套用至進入點方法 ( Main )。 在此情況下,您必須只使用程式碼實作您的應用程式定義 (請參閱應用程式管理概觀)。

另請參閱