Tutorial: Hospedar un control compuesto de WPF en formularios Windows FormsWalkthrough: Hosting a WPF Composite Control in Windows Forms

Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF) Proporciona un entorno rico para crear aplicaciones.provides a rich environment for creating applications. Sin embargo, cuando tiene una inversión sustancial Windows FormsWindows Forms código, puede ser más efectivo extender existentes Windows FormsWindows Forms aplicación con WPFWPF en lugar de a escribirlo desde cero.However, when you have a substantial investment in Windows FormsWindows Forms code, it can be more effective to extend your existing Windows FormsWindows Forms application with WPFWPF rather than to rewrite it from scratch. Un escenario común es cuando quiere insertar uno o más controles implementados con WPFWPF dentro de la aplicación de Windows Forms.A common scenario is when you want to embed one or more controls implemented with WPFWPF within your Windows Forms application. Para obtener más información acerca de cómo personalizar los controles de WPF, vea personalización de controles.For more information about customizing WPF controls, see Control Customization.

Este tutorial le guía a través de una aplicación que hospeda un WPFWPF control compuesto para realizar la entrada de datos en una aplicación de Windows Forms.This walkthrough steps you through an application that hosts a WPFWPF composite control to perform data-entry in a Windows Forms application. El control compuesto se empaqueta en un archivo DLL.The composite control is packaged in a DLL. Este procedimiento general se puede extender a aplicaciones y controles más complejos.This general procedure can be extended to more complex applications and controls. En este tutorial está diseñado para ser casi idéntico en aspecto y funcionalidad al Tutorial: Hospedaje de un Windows Forms Control compuesto de WPF.This walkthrough is designed to be nearly identical in appearance and functionality to Walkthrough: Hosting a Windows Forms Composite Control in WPF. La principal diferencia es que se invierte el escenario de hospedaje.The primary difference is that the hosting scenario is reversed.

Este tutorial está dividido en dos secciones.The walkthrough is divided into two sections. La primera sección describe brevemente la implementación de la WPFWPF control compuesto.The first section briefly describes the implementation of the WPFWPF composite control. La segunda sección explica en detalle cómo hospedar un control compuesto en una aplicación Windows Forms, recibir eventos del control y tener acceso a algunas de las propiedades del control.The second section discusses in detail how to host the composite control in a Windows Forms application, receive events from the control, and access some of the control’s properties.

Las tareas ilustradas en este tutorial incluyen:Tasks illustrated in this walkthrough include:

  • Implementar el control compuesto de WPF.Implementing the WPF composite control.

  • Implementar la aplicación host de Windows Forms.Implementing the Windows Forms host application.

Para obtener una lista de código completo de las tareas ilustradas en este tutorial, vea hospedar un Control compuesto de WPF en Windows Forms Sample.For a complete code listing of the tasks illustrated in this walkthrough, see Hosting a WPF Composite Control in Windows Forms Sample.

Requisitos previosPrerequisites

Necesita Visual Studio para completar este tutorial.You need Visual Studio to complete this walkthrough.

Implementar el control compuesto de WPFImplementing the WPF Composite Control

El WPFWPF control compuesto utilizado en este ejemplo es un formulario de entrada de datos simple que toma el nombre y la dirección del usuario.The WPFWPF composite control used in this example is a simple data-entry form that takes the user's name and address. Cuando el usuario hace clic en uno de los dos botones para indicar que la tarea ha finalizado, el control genera un evento personalizado para devolver esa información al host.When the user clicks one of two buttons to indicate that the task is finished, the control raises a custom event to return that information to the host. En la ilustración siguiente se muestra la representación del control.The following illustration shows the rendered control.

La siguiente imagen muestra un control compuesto de WPF:The following image shows a WPF composite control:

Captura de pantalla que muestra un control simple de WPF.

Crear el proyectoCreating the Project

Para iniciar el proyecto:To start the project:

  1. Iniciar Microsoft Visual StudioMicrosoft Visual Studioy abra el nuevo proyecto cuadro de diálogo.Launch Microsoft Visual StudioMicrosoft Visual Studio, and open the New Project dialog box.

  2. En Visual C# y la categoría de Windows, seleccione el biblioteca de controles de usuario de WPF plantilla.In Visual C# and the Windows category, select the WPF User Control Library template.

  3. Asigne al nuevo proyecto el nombre de MyControls.Name the new project MyControls.

  4. Para la ubicación, especifique una carpeta con el nombre de nivel superior, como WindowsFormsHostingWpfControl.For the location, specify a conveniently named top-level folder, such as WindowsFormsHostingWpfControl. Más tarde, colocará la aplicación host en esta carpeta.Later, you will put the host application in this folder.

  5. Haga clic en Aceptar para crear el proyecto.Click OK to create the project. El proyecto predeterminado contiene un solo control denominado UserControl1.The default project contains a single control named UserControl1.

  6. En el Explorador de soluciones, cambie el nombre UserControl1 a MyControl1.In Solution Explorer, rename UserControl1 to MyControl1.

El proyecto debe tener referencias a los siguientes archivos DLL del sistema.Your project should have references to the following system DLLs. Si alguno de estos archivos DLL no está incluido de forma predeterminada, agréguelos al proyecto.If any of these DLLs are not included by default, add them to your project.

  • PresentationCorePresentationCore

  • PresentationFrameworkPresentationFramework

  • SistemaSystem

  • WindowsBaseWindowsBase

Crear la interfaz de usuarioCreating the User Interface

El interfaz de usuario (UI)user interface (UI) para el control compuesto se implementa con Lenguaje XAML (Extensible Application Markup Language)Extensible Application Markup Language (XAML).The interfaz de usuario (UI)user interface (UI) for the composite control is implemented with Lenguaje XAML (Extensible Application Markup Language)Extensible Application Markup Language (XAML). El control compuesto IUUI consta de cinco TextBox elementos.The composite control IUUI consists of five TextBox elements. Cada TextBox tiene asociado un elemento TextBlock elemento que actúa como una etiqueta.Each TextBox element has an associated TextBlock element that serves as a label. Hay dos Button elementos en la parte inferior, Aceptar y cancelar.There are two Button elements at the bottom, OK and Cancel. Cuando el usuario hace clic en cualquiera de los botones, el control genera un evento personalizado para devolver la información al host.When the user clicks either button, the control raises a custom event to return the information to the host.

Diseño básicoBasic Layout

Los distintos IUUI elementos estén incluidos en un Grid elemento.The various IUUI elements are contained in a Grid element. Puede usar Grid para organizar el contenido de la composición de control prácticamente la misma manera utilizaría un Table elemento de HTML.You can use Grid to arrange the contents of the composite control in much the same way you would use a Table element in HTML. WPFWPF También tiene un Table elemento, pero Grid es más ligero y adecuado para las tareas de diseño simple.also has a Table element, but Grid is more lightweight and better suited for simple layout tasks.

En el siguiente código XAML se muestra el diseño básico.The following XAML shows the basic layout. Este XAML define la estructura general del control especificando el número de columnas y filas en el Grid elemento.This XAML defines the overall structure of the control by specifying the number of columns and rows in the Grid element.

En MyControl1.xaml, reemplace el código XAML existente por el siguiente código XAML.In MyControl1.xaml, replace the existing XAML with the following XAML.

<Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      x:Class="MyControls.MyControl1"
      Background="#DCDCDC"
      Width="375"
      Height="250"
      Name="rootElement"
      Loaded="Init">

  <Grid.ColumnDefinitions>
    <ColumnDefinition Width="Auto" />
    <ColumnDefinition Width="Auto" />
    <ColumnDefinition Width="Auto"/>
    <ColumnDefinition Width="Auto"/>
  </Grid.ColumnDefinitions>

  <Grid.RowDefinitions>
    <RowDefinition Height="Auto" />
    <RowDefinition Height="Auto" />
    <RowDefinition Height="Auto" />
    <RowDefinition Height="Auto" />
    <RowDefinition Height="Auto" />
    <RowDefinition Height="Auto" />
  </Grid.RowDefinitions>
</Grid>

Agregar elementos TextBlock y TextBox a la cuadrículaAdding TextBlock and TextBox Elements to the Grid

Coloca un IUUI elemento en la cuadrícula estableciendo el elemento RowProperty y ColumnProperty atributos para el número apropiado de fila y columna.You place a IUUI element in the grid by setting the element's RowProperty and ColumnProperty attributes to the appropriate row and column number. Recuerde que la numeración de filas y columnas está basada en ceros.Remember that row and column numbering are zero-based. Puede tener un elemento abarque varias columnas estableciendo su ColumnSpanProperty atributo.You can have an element span multiple columns by setting its ColumnSpanProperty attribute. Para obtener más información acerca de Grid elementos, vea crear un elemento Grid.For more information about Grid elements, see Create a Grid Element.

El siguiente XAML muestra el control compuesto TextBox y TextBlock elementos con sus RowProperty y ColumnProperty atributos, que se establecen para colocar correctamente los elementos en la cuadrícula.The following XAML shows the composite control’s TextBox and TextBlock elements with their RowProperty and ColumnProperty attributes, which are set to place the elements properly in the grid.

En MyControl1.xaml, agregue el siguiente XAML dentro de la Grid elemento.In MyControl1.xaml, add the following XAML within the Grid element.

  <TextBlock Grid.Column="0"
        Grid.Row="0" 
        Grid.ColumnSpan="4"
        Margin="10,5,10,0"
        HorizontalAlignment="Center"
        Style="{StaticResource titleText}">Simple WPF Control</TextBlock>

  <TextBlock Grid.Column="0"
        Grid.Row="1"
        Style="{StaticResource inlineText}"
        Name="nameLabel">Name</TextBlock>
  <TextBox Grid.Column="1"
        Grid.Row="1"
        Grid.ColumnSpan="3"
        Name="txtName"/>

  <TextBlock Grid.Column="0"
        Grid.Row="2"
        Style="{StaticResource inlineText}"
        Name="addressLabel">Street Address</TextBlock>
  <TextBox Grid.Column="1"
        Grid.Row="2"
        Grid.ColumnSpan="3"
        Name="txtAddress"/>

  <TextBlock Grid.Column="0"
        Grid.Row="3"
        Style="{StaticResource inlineText}"
        Name="cityLabel">City</TextBlock>
  <TextBox Grid.Column="1"
        Grid.Row="3"
        Width="100"
        Name="txtCity"/>

  <TextBlock Grid.Column="2"
        Grid.Row="3"
        Style="{StaticResource inlineText}"
        Name="stateLabel">State</TextBlock>
  <TextBox Grid.Column="3"
        Grid.Row="3"
        Width="50"
        Name="txtState"/>

  <TextBlock Grid.Column="0"
        Grid.Row="4"
        Style="{StaticResource inlineText}"
        Name="zipLabel">Zip</TextBlock>
  <TextBox Grid.Column="1"
        Grid.Row="4"
        Width="100"
        Name="txtZip"/>

Aplicar estilos a los elementos de interfaz de usuarioStyling the UI Elements

Muchos de los elementos del formulario de entrada de datos tienen un aspecto similar, lo que significa que tienen valores idénticos para varias de sus propiedades.Many of the elements on the data-entry form have a similar appearance, which means that they have identical settings for several of their properties. En lugar de establecer los atributos de cada elemento por separado, se usa el XAML anterior Style elementos para definir valores de propiedad estándar para las clases de elementos.Rather than setting each element's attributes separately, the previous XAML uses Style elements to define standard property settings for classes of elements. Este enfoque reduce la complejidad del control y le permite cambiar la apariencia de varios elementos mediante un solo atributo de estilo.This approach reduces the complexity of the control and enables you to change the appearance of multiple elements through a single style attribute.

El Style elementos estén incluidos en el Grid del elemento Resources propiedad, por lo que se pueden usar en todos los elementos del control.The Style elements are contained in the Grid element's Resources property, so they can be used by all elements in the control. Si es el nombre de un estilo, se aplica a un elemento mediante la adición de un Style elemento establecido en el nombre del estilo.If a style is named, you apply it to an element by adding a Style element set to the style's name. Los estilos que no tienen nombre se convierten en el estilo predeterminado del elemento.Styles that are not named become the default style for the element. Para obtener más información acerca de WPFWPF estilos, consulte aplicar estilos y plantillas.For more information about WPFWPF styles, see Styling and Templating.

El siguiente XAML muestra el Style elementos para el control compuesto.The following XAML shows the Style elements for the composite control. Para ver cómo se aplican los estilos a los elementos, vea el código XAML anterior.To see how the styles are applied to elements, see the previous XAML. Por ejemplo, la última TextBlock elemento tiene el inlineText estilo y el último TextBox elemento utiliza el estilo predeterminado.For example, the last TextBlock element has the inlineText style, and the last TextBox element uses the default style.

En MyControl1.xaml, agregue el XAML siguiente justo después del Grid elemento de inicio.In MyControl1.xaml, add the following XAML just after the Grid start element.

<Grid.Resources>
  <Style x:Key="inlineText" TargetType="{x:Type TextBlock}">
    <Setter Property="Margin" Value="10,5,10,0"/>
    <Setter Property="FontWeight" Value="Normal"/>
    <Setter Property="FontSize" Value="12"/>
  </Style>
  <Style x:Key="titleText" TargetType="{x:Type TextBlock}">
    <Setter Property="DockPanel.Dock" Value="Top"/>
    <Setter Property="FontWeight" Value="Bold"/>
    <Setter Property="FontSize" Value="14"/>
    <Setter Property="Margin" Value="10,5,10,0"/>
  </Style>
  <Style TargetType="{x:Type Button}">
    <Setter Property="Margin" Value="10,5,10,0"/>
    <Setter Property="Width" Value="60"/>
  </Style>
  <Style TargetType="{x:Type TextBox}">
    <Setter Property="Margin" Value="10,5,10,0"/>
  </Style>
</Grid.Resources>

Agregar los botones Aceptar y CancelarAdding the OK and Cancel Buttons

Los elementos finales del control compuesto son el Aceptar y cancelar Button elementos, que ocupan las dos primeras columnas de la última fila de la Grid.The final elements on the composite control are the OK and CancelButton elements, which occupy the first two columns of the last row of the Grid. Estos elementos usan un controlador de eventos comunes, ButtonClickedy el valor predeterminado Button estilo definido en el XAML anterior.These elements use a common event handler, ButtonClicked, and the default Button style defined in the previous XAML.

En MyControl1.xaml, agregue el siguiente XAML después del último TextBox elemento.In MyControl1.xaml, add the following XAML after the last TextBox element. El XAMLXAML parte de un control compuesto ya está completa.The XAMLXAML part of the composite control is now complete.

<Button Grid.Row="5"
        Grid.Column="0"
        Name="btnOK"
        Click="ButtonClicked">OK</Button>
<Button Grid.Row="5"
        Grid.Column="1"
        Name="btnCancel"
        Click="ButtonClicked">Cancel</Button>

Implementar el archivo de código subyacenteImplementing the Code-Behind File

El archivo de código subyacente, MyControl1.xaml.cs, implementa tres tareas esenciales:The code-behind file, MyControl1.xaml.cs, implements three essential tasks:

  1. Controla el evento que se produce cuando el usuario hace clic en uno de los botones.Handles the event that occurs when the user clicks one of the buttons.

  2. Recupera los datos desde el TextBox elementos y lo empaqueta en un objeto de argumento de evento personalizado.Retrieves the data from the TextBox elements, and packages it in a custom event argument object.

  3. Genera personalizado OnButtonClick evento, que notifica al host que el usuario ha terminado y pasa los datos al host.Raises the custom OnButtonClick event, which notifies the host that the user is finished and passes the data back to the host.

El control también expone una serie de propiedades de color y fuente con las que puede cambiar la apariencia.The control also exposes a number of color and font properties that enable you to change the appearance. A diferencia de la WindowsFormsHost (clase), que se utiliza para hospedar un control de Windows Forms, el ElementHost clase expone el control Background solo para la propiedad.Unlike the WindowsFormsHost class, which is used to host a Windows Forms control, the ElementHost class exposes the control’s Background property only. Para mantener la similitud entre este ejemplo de código y el ejemplo tratado en Tutorial: Hospedar un Control compuesto de Windows Forms en WPF, el control expone las propiedades restantes directamente.To maintain the similarity between this code example and the example discussed in Walkthrough: Hosting a Windows Forms Composite Control in WPF, the control exposes the remaining properties directly.

Estructura básica del archivo de código subyacenteThe Basic Structure of the Code-Behind File

El archivo de código subyacente consta de un único espacio de nombres, MyControls, que contendrá dos clases, MyControl1 y MyControlEventArgs.The code-behind file consists of a single namespace, MyControls, which will contain two classes, MyControl1 and MyControlEventArgs.

namespace MyControls  
{  
  public partial class MyControl1 : Grid  
  {  
    //...  
  }  
  public class MyControlEventArgs : EventArgs  
  {  
    //...  
  }  
}  

La primera clase, MyControl1, es una clase parcial que contiene el código que implementa la funcionalidad de la IUUI definida en MyControl1.xaml.The first class, MyControl1, is a partial class containing the code that implements the functionality of the IUUI defined in MyControl1.xaml. Al analizar MyControl1.xaml, el XAMLXAML se convierte en la misma clase parcial, y las dos clases parciales se combinan para formar el control compilado.When MyControl1.xaml is parsed, the XAMLXAML is converted to the same partial class, and the two partial classes are merged to form the compiled control. Por este motivo, el nombre de clase del archivo de código subyacente debe coincidir con el nombre de clase asignado a MyControl1.xaml y debe heredar del elemento raíz del control.For this reason, the class name in the code-behind file must match the class name assigned to MyControl1.xaml, and it must inherit from the root element of the control. La segunda clase, MyControlEventArgs, es una clase de argumentos de evento que se usa para enviar los datos al host.The second class, MyControlEventArgs, is an event arguments class that is used to send the data back to the host.

Abra MyControl1.xaml.cs.Open MyControl1.xaml.cs. Cambie la declaración de clase existente por lo que tiene el siguiente nombre y hereda de Grid.Change the existing class declaration so that it has the following name and inherits from Grid.

public partial class MyControl1 : Grid

Inicializar el controlInitializing the Control

En el código siguiente se implementan varias tareas básicas:The following code implements several basic tasks:

  • Declara un evento privado, OnButtonClicky su delegado asociado, MyControlEventHandler.Declares a private event, OnButtonClick, and its associated delegate, MyControlEventHandler.

  • Crea distintas variables globales privadas que almacenan los datos del usuario.Creates several private global variables that store the user's data. Estos datos se exponen a través de las propiedades correspondientes.This data is exposed through corresponding properties.

  • Implementa un controlador, Init, para el control Loaded eventos.Implements a handler, Init, for the control’s Loaded event. Este controlador inicializa las variables globales al asignarles los valores definidos en MyControl1.xaml.This handler initializes the global variables by assigning them the values defined in MyControl1.xaml. Para ello, usa el Name asignado a una típica TextBlock elemento, nameLabelpara tener acceso a los valores de las propiedades de ese elemento.To do this, it uses the Name assigned to a typical TextBlock element, nameLabel, to access that element's property settings.

Elimine el constructor existente y agregue el código siguiente a su MyControl1 clase.Delete the existing constructor and add the following code to your MyControl1 class.

public delegate void MyControlEventHandler(object sender, MyControlEventArgs args);
public event MyControlEventHandler OnButtonClick;
private FontWeight _fontWeight;
private double _fontSize;
private FontFamily _fontFamily;
private FontStyle _fontStyle;
private SolidColorBrush _foreground;
private SolidColorBrush _background;

private void Init(object sender, EventArgs e)
{
    //They all have the same style, so use nameLabel to set initial values.
    _fontWeight = nameLabel.FontWeight;
    _fontSize = nameLabel.FontSize;
    _fontFamily = nameLabel.FontFamily;
    _fontStyle = nameLabel.FontStyle;
    _foreground = (SolidColorBrush)nameLabel.Foreground;
    _background = (SolidColorBrush)rootElement.Background;
}

Administrar los eventos de clic de los botonesHandling the Buttons' Click Events

El usuario indica que la tarea de entrada de datos ha finalizado con un clic en el Aceptar botón o la cancelar botón.The user indicates that the data-entry task is finished by clicking either the OK button or the Cancel button. Ambos botones usan el mismo Click controlador de eventos, ButtonClicked.Both buttons use the same Click event handler, ButtonClicked. Ambos botones tienen un nombre, btnOK o btnCancel, que permite al controlador determinar qué botón se hizo clic examinando el valor de la sender argumento.Both buttons have a name, btnOK or btnCancel, that enables the handler to determine which button was clicked by examining the value of the sender argument. El controlador hace lo siguiente:The handler does the following:

  • Crea un MyControlEventArgs objeto que contiene los datos de la TextBox elementos.Creates a MyControlEventArgs object that contains the data from the TextBox elements.

  • Si el usuario hizo clic en el cancelar button, conjuntos de la MyControlEventArgs del objeto IsOK propiedad false.If the user clicked the Cancel button, sets the MyControlEventArgs object's IsOK property to false.

  • Provoca el OnButtonClick evento para indicar al host que el usuario ha terminado y devuelve los datos recopilados.Raises the OnButtonClick event to indicate to the host that the user is finished, and passes back the collected data.

Agregue el código siguiente a su MyControl1 clase, después el Init método.Add the following code to your MyControl1 class, after the Init method.

private void ButtonClicked(object sender, RoutedEventArgs e)
{
    MyControlEventArgs retvals = new MyControlEventArgs(true,
                                                        txtName.Text,
                                                        txtAddress.Text,
                                                        txtCity.Text,
                                                        txtState.Text,
                                                        txtZip.Text);
    if (sender == btnCancel)
    {
        retvals.IsOK = false;
    }
    if (OnButtonClick != null)
        OnButtonClick(this, retvals);
}

Crear propiedadesCreating Properties

El resto de la clase simplemente expone propiedades que corresponden a las variables globales que se han descrito anteriormente.The remainder of the class simply exposes properties that correspond to the global variables discussed previously. Cuando se cambia una propiedad, el descriptor de acceso set modifica el aspecto del control cambiando las propiedades de elemento correspondientes y actualizando las variables globales subyacentes.When a property changes, the set accessor modifies the appearance of the control by changing the corresponding element properties and updating the underlying global variables.

Agregue el código siguiente a su MyControl1 clase.Add the following code to your MyControl1 class.

public FontWeight MyControl_FontWeight
{
    get { return _fontWeight; }
    set
    {
        _fontWeight = value;
        nameLabel.FontWeight = value;
        addressLabel.FontWeight = value;
        cityLabel.FontWeight = value;
        stateLabel.FontWeight = value;
        zipLabel.FontWeight = value;
    }
}
public double MyControl_FontSize
{
    get { return _fontSize; }
    set
    {
        _fontSize = value;
        nameLabel.FontSize = value;
        addressLabel.FontSize = value;
        cityLabel.FontSize = value;
        stateLabel.FontSize = value;
        zipLabel.FontSize = value;
    }
}
public FontStyle MyControl_FontStyle
{
    get { return _fontStyle; }
    set
    {
        _fontStyle = value;
        nameLabel.FontStyle = value;
        addressLabel.FontStyle = value;
        cityLabel.FontStyle = value;
        stateLabel.FontStyle = value;
        zipLabel.FontStyle = value;
    }
}
public FontFamily MyControl_FontFamily
{
    get { return _fontFamily; }
    set
    {
        _fontFamily = value;
        nameLabel.FontFamily = value;
        addressLabel.FontFamily = value;
        cityLabel.FontFamily = value;
        stateLabel.FontFamily = value;
        zipLabel.FontFamily = value;
    }
}

public SolidColorBrush MyControl_Background
{
    get { return _background; }
    set
    {
        _background = value;
        rootElement.Background = value;
    }
}
public SolidColorBrush MyControl_Foreground
{
    get { return _foreground; }
    set
    {
        _foreground = value;
        nameLabel.Foreground = value;
        addressLabel.Foreground = value;
        cityLabel.Foreground = value;
        stateLabel.Foreground = value;
        zipLabel.Foreground = value;
    }
}

Devolver los datos al hostSending the Data Back to the Host

El último componente en el archivo es el MyControlEventArgs (clase), que se usa para enviar los datos recopilados al host.The final component in the file is the MyControlEventArgs class, which is used to send the collected data back to the host.

Agregue el código siguiente a su MyControls espacio de nombres.Add the following code to your MyControls namespace. La implementación es sencilla, por lo que no se tratará más adelante.The implementation is straightforward, and is not discussed further.

public class MyControlEventArgs : EventArgs
{
    private string _Name;
    private string _StreetAddress;
    private string _City;
    private string _State;
    private string _Zip;
    private bool _IsOK;

    public MyControlEventArgs(bool result,
                              string name,
                              string address,
                              string city,
                              string state,
                              string zip)
    {
        _IsOK = result;
        _Name = name;
        _StreetAddress = address;
        _City = city;
        _State = state;
        _Zip = zip;
    }

    public string MyName
    {
        get { return _Name; }
        set { _Name = value; }
    }
    public string MyStreetAddress
    {
        get { return _StreetAddress; }
        set { _StreetAddress = value; }
    }
    public string MyCity
    {
        get { return _City; }
        set { _City = value; }
    }
    public string MyState
    {
        get { return _State; }
        set { _State = value; }
    }
    public string MyZip
    {
        get { return _Zip; }
        set { _Zip = value; }
    }
    public bool IsOK
    {
        get { return _IsOK; }
        set { _IsOK = value; }
    }
}

Compile la solución.Build the solution. La compilación generará un archivo DLL denominado MyControls.dll.The build will produce a DLL named MyControls.dll.

Implementar la aplicación host de Windows FormsImplementing the Windows Forms Host Application

Los formularios de Windows hospedar la aplicación usa un ElementHost objeto para hospedar el WPFWPF control compuesto.The Windows Forms host application uses an ElementHost object to host the WPFWPF composite control. La aplicación controla el OnButtonClick eventos para recibir los datos del control compuesto.The application handles the OnButtonClick event to receive the data from the composite control. La aplicación también tiene un conjunto de botones de opción que se pueden usar para modificar la apariencia del control.The application also has a set of option buttons that you can use to modify the control’s appearance. En la siguiente ilustración se muestra la aplicación.The following illustration shows the application.

La siguiente imagen muestra un control compuesto de WPF hospedado en una aplicación de Windows Forms"The following image shows a WPF composite control hosted in a Windows Forms application"

Scteenshot que muestra un control Avalon de hospedaje de formulario de Windows.

Crear el proyectoCreating the Project

Para iniciar el proyecto:To start the project:

  1. Iniciar Visual StudioVisual Studioy abra el nuevo proyecto cuadro de diálogo.Launch Visual StudioVisual Studio, and open the New Project dialog box.

  2. En Visual C# y la categoría de Windows, seleccione el aplicación de Windows Forms plantilla.In Visual C# and the Windows category, select the Windows Forms Application template.

  3. Asigne al nuevo proyecto el nombre de WFHost.Name the new project WFHost.

  4. Para la ubicación, especifique la misma carpeta de nivel superior que contiene el proyecto MyControls.For the location, specify the same top-level folder that contains the MyControls project.

  5. Haga clic en Aceptar para crear el proyecto.Click OK to create the project.

También deberá agregar referencias a la DLL que contiene MyControl1 y a otros ensamblados.You also need to add references to the DLL that contains MyControl1 and other assemblies.

  1. Haga clic en el nombre del proyecto en el Explorador de soluciones y seleccione Agregar referencia.Right-click the project name in Solution Explorer, and select Add Reference.

  2. Haga clic en el examinar pestaña y vaya a la carpeta que contiene MyControls.dll.Click the Browse tab, and browse to the folder that contains MyControls.dll. En este tutorial, esta carpeta es MyControls\bin\Debug.For this walkthrough, this folder is MyControls\bin\Debug.

  3. Seleccione MyControls.dll y, a continuación, haga clic en Aceptar.Select MyControls.dll, and then click OK.

  4. Agregue referencias a los ensamblados siguientes.Add references to the following assemblies.

    • PresentationCorePresentationCore

    • PresentationFrameworkPresentationFramework

    • System.XamlSystem.Xaml

    • WindowsBaseWindowsBase

    • WindowsFormsIntegrationWindowsFormsIntegration

Implementar la interfaz de usuario de la aplicaciónImplementing the User Interface for the Application

La interfaz de usuario de la aplicación de Windows Forms contiene varios controles para interactuar con el control compuesto de WPF.The UI for the Windows Form application contains several controls to interact with the WPF composite control.

  1. Abra Form1 en el Diseñador de Windows Forms.Open Form1 in the Windows Form Designer.

  2. Amplíe el formulario para que quepan los controles.Enlarge the form to accommodate the controls.

  3. En la esquina superior derecha del formulario, agregue un System.Windows.Forms.Panel control para contener el WPFWPF control compuesto.In the upper-right corner of the form, add a System.Windows.Forms.Panel control to hold the WPFWPF composite control.

  4. Agregue las siguientes System.Windows.Forms.GroupBox controles al formulario.Add the following System.Windows.Forms.GroupBox controls to the form.

    NameName TextoText
    groupBox1groupBox1 Color de fondoBackground Color
    groupBox2groupBox2 Color de primer planoForeground Color
    groupBox3groupBox3 Tamaño de fuenteFont Size
    groupBox4groupBox4 Familia de fuentesFont Family
    groupBox5groupBox5 Estilo de fuenteFont Style
    groupBox6groupBox6 Espesor de fuenteFont Weight
    groupBox7groupBox7 Datos del controlData from control
  5. Agregue el siguiente System.Windows.Forms.RadioButton controles a la System.Windows.Forms.GroupBox controles.Add the following System.Windows.Forms.RadioButton controls to the System.Windows.Forms.GroupBox controls.

    GroupBoxGroupBox NameName TextoText
    groupBox1groupBox1 radioBackgroundOriginalradioBackgroundOriginal OriginalOriginal
    groupBox1groupBox1 radioBackgroundLightGreenradioBackgroundLightGreen LightGreenLightGreen
    groupBox1groupBox1 radioBackgroundLightSalmonradioBackgroundLightSalmon LightSalmonLightSalmon
    groupBox2groupBox2 radioForegroundOriginalradioForegroundOriginal OriginalOriginal
    groupBox2groupBox2 radioForegroundRedradioForegroundRed RojoRed
    groupBox2groupBox2 radioForegroundYellowradioForegroundYellow AmarilloYellow
    groupBox3groupBox3 radioSizeOriginalradioSizeOriginal OriginalOriginal
    groupBox3groupBox3 radioSizeTenradioSizeTen 1010
    groupBox3groupBox3 radioSizeTwelveradioSizeTwelve 1212
    groupBox4groupBox4 radioFamilyOriginalradioFamilyOriginal OriginalOriginal
    groupBox4groupBox4 radioFamilyTimesradioFamilyTimes Times New RomanTimes New Roman
    groupBox4groupBox4 radioFamilyWingDingsradioFamilyWingDings WingDingsWingDings
    groupBox5groupBox5 radioStyleOriginalradioStyleOriginal NormalNormal
    groupBox5groupBox5 radioStyleItalicradioStyleItalic CursivaItalic
    groupBox6groupBox6 radioWeightOriginalradioWeightOriginal OriginalOriginal
    groupBox6groupBox6 radioWeightBoldradioWeightBold NegritaBold
  6. Agregue el siguiente System.Windows.Forms.Label controla al último System.Windows.Forms.GroupBox.Add the following System.Windows.Forms.Label controls to the last System.Windows.Forms.GroupBox. Estos controles muestran los datos devueltos por la WPFWPF control compuesto.These controls display the data returned by the WPFWPF composite control.

    GroupBoxGroupBox NameName TextoText
    groupBox7groupBox7 lblNamelblName Nombre:Name:
    groupBox7groupBox7 lblAddresslblAddress Dirección postal:Street Address:
    groupBox7groupBox7 lblCitylblCity Ciudad:City:
    groupBox7groupBox7 lblStatelblState Estado:State:
    groupBox7groupBox7 lblZiplblZip Código postal:Zip:

Inicializar el formularioInitializing the Form

Se suele implementa el código de hospedaje en el formulario Load controlador de eventos.You generally implement the hosting code in the form's Load event handler. El siguiente código muestra la Load controlador de eventos, un controlador para el WPFWPF del control compuesto Loaded eventos y declaraciones de distintas variables globales que se usan más adelante.The following code shows the Load event handler, a handler for the WPFWPF composite control’s Loaded event, and declarations for several global variables that are used later.

En el Diseñador de formularios de Windows, haga doble clic en el formulario para crear un Load controlador de eventos.In the Windows Forms Designer, double-click the form to create a Load event handler. En la parte superior del archivo Form1.cs, agregue las siguientes using instrucciones.At the top of Form1.cs, add the following using statements.

using System.Windows;
using System.Windows.Forms.Integration;
using System.Windows.Media;

Reemplace el contenido de la existente Form1 con el código siguiente.Replace the contents of the existing Form1 class with the following code.

private ElementHost ctrlHost;
private MyControls.MyControl1 wpfAddressCtrl;
System.Windows.FontWeight initFontWeight;
double initFontSize;
System.Windows.FontStyle initFontStyle;
System.Windows.Media.SolidColorBrush initBackBrush;
System.Windows.Media.SolidColorBrush initForeBrush;
System.Windows.Media.FontFamily initFontFamily;

public Form1()
{
    InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)
{
    ctrlHost = new ElementHost();
    ctrlHost.Dock = DockStyle.Fill;
    panel1.Controls.Add(ctrlHost);
    wpfAddressCtrl = new MyControls.MyControl1();
    wpfAddressCtrl.InitializeComponent();
    ctrlHost.Child = wpfAddressCtrl;

    wpfAddressCtrl.OnButtonClick +=
        new MyControls.MyControl1.MyControlEventHandler(
        avAddressCtrl_OnButtonClick);
    wpfAddressCtrl.Loaded += new RoutedEventHandler(
        avAddressCtrl_Loaded);
}

void avAddressCtrl_Loaded(object sender, EventArgs e)
{
    initBackBrush = (SolidColorBrush)wpfAddressCtrl.MyControl_Background;
    initForeBrush = wpfAddressCtrl.MyControl_Foreground;
    initFontFamily = wpfAddressCtrl.MyControl_FontFamily;
    initFontSize = wpfAddressCtrl.MyControl_FontSize;
    initFontWeight = wpfAddressCtrl.MyControl_FontWeight;
    initFontStyle = wpfAddressCtrl.MyControl_FontStyle;
}

El Form1_Load método en el código anterior muestra el procedimiento general para hospedar un WPFWPF control:The Form1_Load method in the preceding code shows the general procedure for hosting a WPFWPF control:

  1. Cree un nuevo ElementHost objeto.Create a new ElementHost object.

  2. Establecer el control Dock propiedad DockStyle.Fill.Set the control's Dock property to DockStyle.Fill.

  3. Agregar el ElementHost el control a la Panel del control Controls colección.Add the ElementHost control to the Panel control's Controls collection.

  4. Cree una instancia de la WPFWPF control.Create an instance of the WPFWPF control.

  5. Hospedar un control compuesto en el formulario asignando el control a la ElementHost del control Child propiedad.Host the composite control on the form by assigning the control to the ElementHost control's Child property.

Las dos líneas restantes en el Form1_Load método asociar controladores a dos eventos de control:The remaining two lines in the Form1_Load method attach handlers to two control events:

  • OnButtonClick es un evento personalizado que se activa el control compuesto cuando el usuario hace clic en el Aceptar o cancelar botón.is a custom event that is fired by the composite control when the user clicks the OK or Cancel button. El evento se controla para obtener la respuesta del usuario y recopilar los datos que este haya especificado.You handle the event to get the user's response and to collect any data that the user specified.

  • Loaded es un evento estándar generado por un WPFWPF control al se ha cargado completamente.is a standard event that is raised by a WPFWPF control when it is fully loaded. El evento se usa aquí porque el ejemplo necesita inicializar distintas variables globales usando las propiedades del control.The event is used here because the example needs to initialize several global variables using properties from the control. En el momento de la forma Load eventos, el control no está totalmente cargado y esos valores todavía están establecidos en null.At the time of the form's Load event, the control is not fully loaded and those values are still set to null. Deberá esperar hasta que el control Loaded evento se produce antes de que se pueden acceder a esas propiedades.You need to wait until the control’s Loaded event occurs before you can access those properties.

El Loaded controlador de eventos se muestra en el código anterior.The Loaded event handler is shown in the preceding code. El OnButtonClick controlador se describe en la sección siguiente.The OnButtonClick handler is discussed in the next section.

Administrar OnButtonClickHandling OnButtonClick

El OnButtonClick evento tiene lugar cuando el usuario hace clic en el Aceptar o cancelar botón.The OnButtonClick event occurs when the user clicks the OK or Cancel button.

El controlador de eventos comprueba el argumento de evento IsOK campo para determinar qué botón se hizo clic.The event handler checks the event argument's IsOK field to determine which button was clicked. El lbl datos variables corresponden a la Label controles descritos anteriormente.The lbldata variables correspond to the Label controls that were discussed earlier. Si el usuario hace clic en el Aceptar botón, los datos desde el control TextBox controles se asigna a la correspondiente Label control.If the user clicks the OK button, the data from the control’s TextBox controls is assigned to the corresponding Label control. Si el usuario hace clic cancelar, el Text valores se establecen en las cadenas predeterminadas.If the user clicks Cancel, the Text values are set to the default strings.

Agregue el siguiente botón haga clic en el código de controlador de eventos para el Form1 clase.Add the following button click event handler code to the Form1 class.

void avAddressCtrl_OnButtonClick(
    object sender,
    MyControls.MyControl1.MyControlEventArgs args)
{
    if (args.IsOK)
    {
        lblAddress.Text = "Street Address: " + args.MyStreetAddress;
        lblCity.Text = "City: " + args.MyCity;
        lblName.Text = "Name: " + args.MyName;
        lblState.Text = "State: " + args.MyState;
        lblZip.Text = "Zip: " + args.MyZip;
    }
    else
    {
        lblAddress.Text = "Street Address: ";
        lblCity.Text = "City: ";
        lblName.Text = "Name: ";
        lblState.Text = "State: ";
        lblZip.Text = "Zip: ";
    }
}

Compile y ejecute la aplicación.Build and run the application. Agregue texto en el control compuesto de WPF y, a continuación, haga clic en Aceptar.Add some text in the WPF composite control and then click OK. El texto aparece en las etiquetas.The text appears in the labels. En este momento, no se ha agregado código para controlar los botones de radio.At this point, code has not been added to handle the radio buttons.

Modificar la apariencia del controlModifying the Appearance of the Control

El RadioButton controles del formulario permitirá al usuario cambiar la WPFWPF colores de primer plano y fondo del control compuesto, así como varias propiedades de fuente.The RadioButton controls on the form will enable the user to change the WPFWPF composite control’s foreground and background colors as well as several font properties. El color de fondo se expone mediante el ElementHost objeto.The background color is exposed by the ElementHost object. Las propiedades restantes se exponen como propiedades personalizadas del control.The remaining properties are exposed as custom properties of the control.

Haga doble clic en cada uno de ellos RadioButton control en el formulario para crear CheckedChanged controladores de eventos.Double-click each RadioButton control on the form to create CheckedChanged event handlers. Reemplace el CheckedChanged controladores de eventos con el código siguiente.Replace the CheckedChanged event handlers with the following code.

private void radioBackgroundOriginal_CheckedChanged(object sender, EventArgs e)
{
    wpfAddressCtrl.MyControl_Background = initBackBrush;
}

private void radioBackgroundLightGreen_CheckedChanged(object sender, EventArgs e)
{
    wpfAddressCtrl.MyControl_Background = new SolidColorBrush(Colors.LightGreen);
}

private void radioBackgroundLightSalmon_CheckedChanged(object sender, EventArgs e)
{
    wpfAddressCtrl.MyControl_Background = new SolidColorBrush(Colors.LightSalmon);
}

private void radioForegroundOriginal_CheckedChanged(object sender, EventArgs e)
{
    wpfAddressCtrl.MyControl_Foreground = initForeBrush;
}

private void radioForegroundRed_CheckedChanged(object sender, EventArgs e)
{
    wpfAddressCtrl.MyControl_Foreground = new System.Windows.Media.SolidColorBrush(Colors.Red);
}

private void radioForegroundYellow_CheckedChanged(object sender, EventArgs e)
{
    wpfAddressCtrl.MyControl_Foreground = new System.Windows.Media.SolidColorBrush(Colors.Yellow);
}

private void radioFamilyOriginal_CheckedChanged(object sender, EventArgs e)
{
    wpfAddressCtrl.MyControl_FontFamily = initFontFamily;
}

private void radioFamilyTimes_CheckedChanged(object sender, EventArgs e)
{
    wpfAddressCtrl.MyControl_FontFamily = new System.Windows.Media.FontFamily("Times New Roman");
}

private void radioFamilyWingDings_CheckedChanged(object sender, EventArgs e)
{
    wpfAddressCtrl.MyControl_FontFamily = new System.Windows.Media.FontFamily("WingDings");
}

private void radioSizeOriginal_CheckedChanged(object sender, EventArgs e)
{
    wpfAddressCtrl.MyControl_FontSize = initFontSize;
}

private void radioSizeTen_CheckedChanged(object sender, EventArgs e)
{
    wpfAddressCtrl.MyControl_FontSize = 10;
}

private void radioSizeTwelve_CheckedChanged(object sender, EventArgs e)
{
    wpfAddressCtrl.MyControl_FontSize = 12;
}

private void radioStyleOriginal_CheckedChanged(object sender, EventArgs e)
{
    wpfAddressCtrl.MyControl_FontStyle = initFontStyle;
}

private void radioStyleItalic_CheckedChanged(object sender, EventArgs e)
{
    wpfAddressCtrl.MyControl_FontStyle = System.Windows.FontStyles.Italic;
}

private void radioWeightOriginal_CheckedChanged(object sender, EventArgs e)
{
    wpfAddressCtrl.MyControl_FontWeight = initFontWeight;
}

private void radioWeightBold_CheckedChanged(object sender, EventArgs e)
{
    wpfAddressCtrl.MyControl_FontWeight = FontWeights.Bold;
}

Compile y ejecute la aplicación.Build and run the application. Haga clic en los diferentes botones de radio para ver el efecto en el control compuesto de WPF.Click the different radio buttons to see the effect on the WPF composite control.

Vea tambiénSee also