方法 : UI を返すアドインを作成する

更新 : 2007 年 11 月

この例では、ホスト WPF スタンドアロン アプリケーションに Windows Presentation Foundation (WPF)ユーザー インターフェイス (UI) を返すアドインを作成する方法を示します。

このアドインが返す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 のアドインの概要