共用方式為


HOW TO:建立傳回 UI 的增益集

更新:2007 年 11 月

本範例示範如何建立可將 Windows Presentation Foundation (WPF) 使用者介面 (UI) 傳回主 WPF 獨立應用程式的增益集 (Add-In)。

此增益集所傳回的 UI 是 WPF 使用者控制項。這個使用者控制項的內容是單一按鈕,當按下時,會顯示訊息方塊。WPF 獨立應用程式則裝載增益集,會將使用者控制項 (由增益集傳回) 顯示為主應用程式視窗的內容。

必要條件

這個範例的重點是 .NET Framework 增益集模型實現此案例的 WPF 擴充,並假設下列項目:

範例

如需本主題隨附的完整範例,請參閱增益集傳回 UI 範例

範例

若要建立傳回 WPF UI 的增益集,每個管線區段、增益集和主應用程式都需要特定的程式碼。

實作合約管線區段

方法必須由傳回 UI 的合約所定義,且傳回值必須是型別 INativeHandleContract。下列程式碼中以 IWPFAddInContract 合約的 GetAddInUI 方法來示範。

using System.AddIn.Contract; // IContract, INativeHandleContract
using System.AddIn.Pipeline; // AddInContractAttribute

namespace Contracts
{
    /// <summary>
    /// Defines the services that an add-in will provide to a host application
    /// </summary>
    [AddInContract]
    public interface IWPFAddInContract : IContract
    {
        // Return a UI to the host application
        INativeHandleContract GetAddInUI();
    }
}

實作增益集檢視管線區段

因為增益集實作 UI,提供做為 FrameworkElement 的子類別,增益集檢視上與 IWPFAddInView.GetAddInUI 關聯的方法,必須傳回型別為 FrameworkElement 的值。下列程式碼顯示合約的增益集檢視,實作為介面。

using System.AddIn.Pipeline; // AddInBaseAttribute
using System.Windows; // FrameworkElement

namespace AddInViews
{
    /// <summary>
    /// Defines the add-in's view of the contract
    /// </summary>
    [AddInBase]
    public interface IWPFAddInView
    {
        // The add-in's implementation of this method will return
        // a UI type that directly or indirectly derives from 
        // FrameworkElement.
        FrameworkElement GetAddInUI();
    }
}

實作增益集端配接器管線區段

合約方法傳回 INativeHandleContract,但增益集傳回 FrameworkElement (如增益集檢視所指定)。因此,在跨越隔離界限之前,FrameworkElement 必須轉換為 INativeHandleContract。這個工作是由增益集端配接器藉由呼叫 ViewToContractAdapter 來執行的,如下列程式碼所示。

using System.AddIn.Contract; // INativeHandleContract
using System.AddIn.Pipeline; // AddInAdapterAttribute, FrameworkElementAdapters, ContractBase
using System.Windows; // FrameworkElement

using AddInViews; // IWPFAddInView
using Contracts; // IWPFAddInContract

namespace AddInSideAdapters
{
    /// <summary>
    /// Adapts the add-in's view of the contract to the add-in contract
    /// </summary>
    [AddInAdapter]
    public class WPFAddIn_ViewToContractAddInSideAdapter : ContractBase, IWPFAddInContract
    {
        IWPFAddInView wpfAddInView;

        public WPFAddIn_ViewToContractAddInSideAdapter(IWPFAddInView wpfAddInView)
        {
            // Adapt the add-in view of the contract (IWPFAddInView) 
            // to the contract (IWPFAddInContract)
            this.wpfAddInView = wpfAddInView;
        }

        public INativeHandleContract GetAddInUI()
        {
            // Convert the FrameworkElement from the add-in to an INativeHandleContract 
            // that will be passed across the isolation boundary to the host application.
            FrameworkElement fe = this.wpfAddInView.GetAddInUI();
            INativeHandleContract inhc = FrameworkElementAdapters.ViewToContractAdapter(fe);
            return inhc;
        }
    }
}

實作主應用程式檢視管線區段

因為主應用程式會顯示 FrameworkElement,主應用程式檢視上與 IWPFAddInHostView.GetAddInUI 關聯的方法,必須傳回型別為 FrameworkElement 的值。下列程式碼顯示合約的主應用程式檢視,實作為介面。

using System.Windows; // FrameworkElement

namespace HostViews
{
    /// <summary>
    /// Defines the host's view of the add-in
    /// </summary>
    public interface IWPFAddInHostView
    {
        // The view returns as a class that directly or indirectly derives from 
        // FrameworkElement and can subsequently be displayed by the host 
        // application by embedding it as content or sub-content of a UI that is 
        // implemented by the host application.
        FrameworkElement GetAddInUI();
    }
}

實作主應用程式端配接器管線區段

合約方法傳回 INativeHandleContract,但主應用程式預期是 FrameworkElement (如主應用程式檢視所指定)。因此,在跨越隔離界限之後,INativeHandleContract 必須轉換為 FrameworkElement。這個工作是由主應用程式端配接器藉由呼叫 ContractToViewAdapter 來執行的,如下列程式碼所示。

using System.AddIn.Contract; // INativeHandleContract
using System.AddIn.Pipeline; // HostAdapterAttribute, FrameworkElementAdapters, ContractHandle
using System.Windows; // FrameworkElement

using Contracts; // IWPFAddInContract
using HostViews; // IWPFAddInHostView

namespace HostSideAdapters
{
    /// <summary>
    /// Adapts the add-in contract to the host's view of the add-in
    /// </summary>
    [HostAdapter]
    public class WPFAddIn_ContractToViewHostSideAdapter : IWPFAddInHostView
    {
        IWPFAddInContract wpfAddInContract;
        ContractHandle wpfAddInContractHandle;

        public WPFAddIn_ContractToViewHostSideAdapter(IWPFAddInContract wpfAddInContract)
        {
            // Adapt the contract (IWPFAddInContract) to the host application's
            // view of the contract (IWPFAddInHostView)
            this.wpfAddInContract = wpfAddInContract;

            // Prevent the reference to the contract from being released while the
            // host application uses the add-in
            this.wpfAddInContractHandle = new ContractHandle(wpfAddInContract);
        }

        public FrameworkElement GetAddInUI()
        {
            // Convert the INativeHandleContract that was passed from the add-in side
            // of the isolation boundary to a FrameworkElement
            INativeHandleContract inhc = this.wpfAddInContract.GetAddInUI();
            FrameworkElement fe = FrameworkElementAdapters.ContractToViewAdapter(inhc);
            return fe;
        }
    }
}

實作增益集

隨著增益集端配接器和增益集檢視的建立,增益集 (WPFAddIn1.AddIn) 必須實作 IWPFAddInView.GetAddInUI 方法以傳回 FrameworkElement 物件 (本範例中的 UserControl)。下列程式碼顯示 UserControl 的實作 AddInUI。

    <UserControl
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="WPFAddIn1.AddInUI">

    <StackPanel>
        <Button Click="clickMeButton_Click" Content="Click Me!" />
    </StackPanel>

</UserControl>
using System.Windows; // MessageBox, RoutedEventArgs
using System.Windows.Controls; // UserControl

namespace WPFAddIn1
{
    public partial class AddInUI : UserControl
    {
        public AddInUI()
        {
            InitializeComponent();
        }

        void clickMeButton_Click(object sender, RoutedEventArgs e)
        {
            MessageBox.Show("Hello from WPFAddIn1");
        }
    }
}

增益集實作的 IWPFAddInView.GetAddInUI 只需要傳回 AddInUI 的新執行個體,如下列程式碼所示。

using System.AddIn; // AddInAttribute
using System.Windows; // FrameworkElement

using AddInViews; // IWPFAddInView

namespace WPFAddIn1
{
    /// <summary>
    /// Add-In implementation
    /// </summary>
    [AddIn("WPF Add-In 1")]
    public class WPFAddIn : IWPFAddInView
    {
        public FrameworkElement GetAddInUI()
        {
            // Return add-in UI
            return new AddInUI();
        }
    }
}

實作主應用程式

隨著主應用程式端配接器和主應用程式檢視的建立,主應用程式可以使用 .NET Framework 增益集模型開啟管線、取得增益集的主應用程式檢視,以及呼叫 IWPFAddInHostView.GetAddInUI 方法。這些步驟顯示在下列程式碼中。

// Get add-in pipeline folder (the folder in which this application was launched from)
string appPath = Environment.CurrentDirectory;

// Rebuild visual add-in pipeline
string[] warnings = AddInStore.Rebuild(appPath);
if (warnings.Length > 0)
{
    string msg = "Could not rebuild pipeline:";
    foreach (string warning in warnings) msg += "\n" + warning;
    MessageBox.Show(msg);
    return;
}

// Activate add-in with Internet zone security isolation
Collection<AddInToken> addInTokens = AddInStore.FindAddIns(typeof(IWPFAddInHostView), appPath);
AddInToken wpfAddInToken = addInTokens[0];
this.wpfAddInHostView = wpfAddInToken.Activate<IWPFAddInHostView>(AddInSecurityLevel.Internet);

// Get and display add-in UI
FrameworkElement addInUI = this.wpfAddInHostView.GetAddInUI();
this.addInUIHostGrid.Children.Add(addInUI);

請參閱

工作

增益集傳回 UI 範例

概念

增益集概觀

Windows Presentation Foundation 增益集概觀