Compartir a través de


Cómo: Crear un complemento que devuelva una interfaz de usuario

Actualización: noviembre 2007

En este ejemplo se muestra cómo crear un complemento que devuelve una interfaz de usuario (UI) de Windows Presentation Foundation (WPF) a una aplicación host WPF independiente.

El complemento devuelve una interfaz de usuario que es un control de usuario de WPF. El contenido del control de usuario es un botón único que muestra un cuadro de mensaje cuando se hace clic en él. La aplicación WPF independiente hospeda el complemento y muestra el control de usuario (devuelto por el complemento) como el contenido de la ventana de la aplicación principal.

Requisitos previos

En este ejemplo se resaltan las extensiones de WPF del modelo de complementos de .NET Framework que habilitan este escenario y se supone lo siguiente:

Ejemplo

Para obtener el ejemplo completo que acompaña a este tema, vea Ejemplo Add-In Returns a UI.

Ejemplo

Para crear un complemento que devuelve una interfaz de usuario de WPF se necesita un código concreto para cada segmento de la canalización, el complemento y la aplicación host.

Implementar el segmento de canalización del contrato

El contrato debe definir un método para devolver una interfaz de usuario y su valor devuelto debe ser de tipo INativeHandleContract. El método GetAddInUI del contrato IWPFAddInContract lo muestra en el código siguiente.

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();
    }
}

Implementar el segmento de canalización de la vista de complemento

Dado que el complemento implementa las UIs que proporciona como subclases de FrameworkElement, el método en la vista de complemento que guarda correlación con IWPFAddInView.GetAddInUI debe devolver un valor de tipo FrameworkElement. En el código siguiente se muestra la vista de complemento del contrato, implementada como una interfaz.

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();
    }
}

Implementar el segmento de canalización del adaptador del complemento

El método del contrato devuelve una interfaz INativeHandleContract, pero el complemento devuelve un objeto FrameworkElement (según lo especificado en la vista de complemento). Por consiguiente, el objeto FrameworkElement se debe convertir en una interfaz INativeHandleContract antes de cruzar el límite de aislamiento. Este trabajo lo realiza el adaptador del complemento mediante una llamada a ViewToContractAdapter, como se muestra en el código siguiente.

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;
        }
    }
}

Implementar el segmento de canalización de la vista de host

Dado que la aplicación host mostrará un objeto FrameworkElement, el método en la vista de host que guarda correlación con IWPFAddInHostView.GetAddInUI debe devolver un valor de tipo FrameworkElement. En el código siguiente se muestra la vista de host del contrato, implementada como una interfaz.

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();
    }
}

Implementar el segmento de canalización del adaptador del host

El método del contrato devuelve una interfaz INativeHandleContract, pero la aplicación host espera un objeto FrameworkElement (según lo especificado por la vista de host). Por consiguiente, la interfaz INativeHandleContract se debe convertir en un objeto FrameworkElement después de cruzar el límite de aislamiento. Este trabajo lo realiza el adaptador del host mediante una llamada a ContractToViewAdapter, como se muestra en el código siguiente.

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;
        }
    }
}

Implementar el complemento

Con el adaptador y la vista de complemento creados, el complemento (WPFAddIn1.AddIn) debe implementar el método IWPFAddInView.GetAddInUI para que se devuelva un objeto FrameworkElement (UserControl en este ejemplo). La implementación de UserControl, AddInUI, se muestra en el código siguiente.

    <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");
        }
    }
}

La implementación de IWPFAddInView.GetAddInUI por parte del complemento únicamente tiene que devolver una nueva instancia de AddInUI, como se muestra en el código siguiente.

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();
        }
    }
}

Implementar la aplicación host

Con el adaptador y la vista de host creados, la aplicación host puede utilizar el modelo de complementos de .NET Framework para abrir la canalización, adquirir una vista de host del complemento y llamar al método IWPFAddInHostView.GetAddInUI. Estos pasos se muestran en el código siguiente.

// 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);

Vea también

Tareas

Ejemplo Add-In Returns a UI

Conceptos

Información general sobre complementos

Información general sobre complementos de Windows Presentation Foundation