Tutorial: Hospedar un control compuesto de WPF en formularios Windows Forms

Windows Presentation Foundation (WPF) proporciona un entorno enriquecido para crear aplicaciones. Pero si ha realizado una inversión sustancial en código de Windows Forms, puede resultar más efectivo extender la aplicación existente de Windows Forms con WPF, en lugar de volver a escribirlo desde cero. Un escenario común es cuando quiere insertar uno o más controles implementados con WPF en una aplicación de Windows Forms. Para más información sobre cómo personalizar los controles de WPF, vea Personalización de controles.

Este tutorial le guía por una aplicación que hospeda un control compuesto de WPF para realizar la entrada de datos en una aplicación de Windows Forms. El control compuesto se empaqueta en un archivo DLL. Este procedimiento general se puede extender a aplicaciones y controles más complejos. Este tutorial está diseñado para ser casi idéntico en aspecto y funcionalidad al Tutorial: Hospedaje de un control compuesto de Windows Forms en WPF. La principal diferencia es que se invierte el escenario de hospedaje.

Este tutorial está dividido en dos secciones. En la primera sección se describe brevemente la implementación del control compuesto de WPF. En la segunda sección se explica en detalle cómo hospedar un control compuesto en una aplicación de Windows Forms, recibir eventos del control y acceder a algunas de las propiedades del control.

Las tareas ilustradas en este tutorial incluyen:

  • Implementar el control compuesto de WPF.

  • Implementar la aplicación host de Windows Forms.

Para obtener una lista de código completa con las tareas descritas en este tutorial, vea Ejemplo de hospedaje de un control compuesto de WPF en Windows Forms.

Requisitos previos

Necesita Visual Studio para completar este tutorial.

Implementar el control compuesto de WPF

El control compuesto de WPF que se usa en este ejemplo es un formulario de entrada de datos simple que toma el nombre y la dirección del usuario. 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. En la ilustración siguiente se muestra la representación del control.

En la imagen siguiente se muestra un control compuesto de WPF:

Captura de pantalla que muestra un control de WPF simple.

Crear el proyecto

Para iniciar el proyecto:

  1. Inicie Visual Studio y abra el cuadro de diálogo Nuevo proyecto.

  2. En Visual C# y en la categoría de Windows, seleccione la plantilla Biblioteca de controles de usuario de WPF.

  3. Asigne al nuevo proyecto el nombre de MyControls.

  4. Para la ubicación, especifique una carpeta de nivel superior con un nombre adecuado, como WindowsFormsHostingWpfControl. Más tarde, colocará la aplicación host en esta carpeta.

  5. Haga clic en Aceptar para crear el proyecto. El proyecto predeterminado contiene un solo control denominado UserControl1.

  6. En el Explorador de soluciones, cambie el nombre de UserControl1 a MyControl1.

El proyecto debe tener referencias a los siguientes archivos DLL del sistema. Si alguno de estos archivos DLL no está incluido de forma predeterminada, agréguelos al proyecto.

  • PresentationCore

  • PresentationFramework

  • Sistema

  • WindowsBase

Crear la interfaz de usuario

La interfaz de usuario (UI) del control compuesto se implementa con lenguaje XAML. La interfaz de usuario del control compuesto consta de cinco elementos TextBox. Cada elemento TextBox tiene un elemento TextBlock asociado que actúa de etiqueta. En la parte inferior hay dos elementos Button: Aceptar y Cancelar. Cuando el usuario hace clic en cualquiera de los botones, el control genera un evento personalizado para devolver la información al host.

Diseño básico

Los distintos elementos de la interfaz de usuario se incluyen en un elemento Grid. Puede usar Grid para organizar el contenido del control compuesto prácticamente de la misma manera en la que usaría un elemento Table en HTML. WPF también tiene un elemento Table, pero Grid es más ligero y más indicado para tareas de diseño sencillas.

En el siguiente código XAML se muestra el diseño básico. En este código XAML se define la estructura general del control mediante la especificación del número de columnas y filas del elemento Grid.

En MyControl1.xaml, reemplace el código XAML existente por el siguiente código 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ícula

Para colocar un elemento de interfaz de usuario en la cuadrícula, debe establecer loa atributos RowProperty y ColumnProperty del elemento en el número de fila y columna adecuado. Recuerde que la numeración de filas y columnas está basada en ceros. Un elemento puede abarcar varias columnas si establece su atributo ColumnSpanProperty. Para más información sobre los elementos Grid, vea Creación de un elemento de cuadrícula.

En el código XAML se muestran los elementos TextBox y TextBlock del control compuesto con sus atributos RowProperty y ColumnProperty, que se establecen para colocar los elementos de forma correcta en la cuadrícula.

En MyControl1.xaml, agregue el código XAML siguiente dentro del elemento Grid.

  <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 usuario

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. En lugar de establecer por separado los atributos de cada elemento, en el código XAML anterior se usan elementos Style a fin de definir valores de propiedad estándar para las clases de elementos. Este enfoque reduce la complejidad del control y le permite cambiar la apariencia de varios elementos mediante un solo atributo de estilo.

Los elementos Style se incluyen en la propiedad Resources del elemento Grid, para que los puedan usar todos los elementos del control. Si un estilo tiene nombre, puede aplicarlo a un elemento si agrega un elemento Style establecido en el nombre del estilo. Los estilos que no tienen nombre se convierten en el estilo predeterminado del elemento. Para más información sobre los estilos de WPF, vea Aplicación de estilos y plantillas.

En el código XAML siguiente se muestran los elementos Style para el control compuesto. Para ver cómo se aplican los estilos a los elementos, vea el código XAML anterior. Por ejemplo, el último elemento TextBlock tiene el estilo inlineText y el último elemento TextBox usa el estilo predeterminado.

En MyControl1.xaml, agregue el código XAML siguiente justo después del elemento de inicio Grid.

<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 Cancelar

Los elementos finales del control compuesto son los elementos ButtonAceptar y Cancelar, que ocupan las dos primeras columnas de la última fila del elemento Grid. Estos elementos usan un controlador de eventos común, ButtonClicked, y el estilo Button predeterminado definido en el código XAML anterior.

En MyControl1.xaml, agregue el código XAML siguiente después del último elemento TextBox. La parte XAML del control compuesto ya está completa.

<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 subyacente

El archivo de código subyacente, MyControl1.xaml.cs, implementa tres tareas esenciales:

  1. Controla el evento que se produce cuando el usuario hace clic en uno de los botones.

  2. Recupera los datos de los elementos TextBox y los empaqueta en un objeto de argumento de evento personalizado.

  3. Genera el evento OnButtonClick personalizado, que notifica al host que el usuario ha terminado y devuelve los datos al host.

El control también expone una serie de propiedades de color y fuente con las que puede cambiar la apariencia. A diferencia de la clase WindowsFormsHost, que se usa para hospedar un control de Windows Forms, la clase ElementHost solo expone la propiedad Background del control. Para mantener la similitud entre este ejemplo de código y el descrito en Tutorial: Hospedaje de un control compuesto de Windows Forms en WPF, el control expone directamente las propiedades restantes.

Estructura básica del archivo de código subyacente

El archivo de código subyacente consta de un único espacio de nombres, MyControls, que contiene dos clases, MyControl1 y MyControlEventArgs.

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

La primera, MyControl1, es una clase parcial que contiene el código que implementa la funcionalidad de la interfaz de usuario definida en MyControl1.xaml. Al analizar MyControl1.xaml, el código XAML se convierte en la misma clase parcial y las dos clases parciales se combinan para formar el control compilado. 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. La segunda clase, MyControlEventArgs, es una clase de argumentos de evento que se usa para devolver los datos al host.

Abra MyControl1.xaml.cs. Cambie la declaración de clase existente para que tenga el siguiente nombre y herede de Grid.

public partial class MyControl1 : Grid

Inicializar el control

En el código siguiente se implementan varias tareas básicas:

  • Declara un evento privado, OnButtonClick, y su delegado asociado, MyControlEventHandler.

  • Crea distintas variables globales privadas que almacenan los datos del usuario. Estos datos se exponen a través de las propiedades correspondientes.

  • Implementa un controlador, Init, para el evento Loaded del control. Este controlador inicializa las variables globales al asignarles los valores definidos en MyControl1.xaml. Para hacerlo, usa el objeto Name asignado a un elemento TextBlock típico, nameLabel, para acceder a los valores de propiedad de ese elemento.

Elimine el constructor existente y agregue el código siguiente a la clase MyControl1.

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 botones

El usuario indica que la tarea de entrada de datos ha finalizado, para lo que hace clic en el botón Aceptar o Cancelar. Los dos botones usan el mismo controlador de eventos Click, ButtonClicked. Los dos botones tienen un nombre, btnOK o btnCancel, que permite al controlador determinar en qué botón se ha hecho clic mediante el examen del valor del argumento sender. El controlador hace lo siguiente:

  • Crea un objeto MyControlEventArgs que contiene los datos de los elementos TextBox.

  • Si el usuario ha hecho clic en el botón Cancelar, la propiedad IsOK del objeto MyControlEventArgs se establece en false.

  • Genera el evento OnButtonClick para indicar al host que el usuario ha terminado y devuelve los datos recopilados.

Agregue el código siguiente a la clase MyControl1, después del método Init.

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 propiedades

El resto de la clase simplemente expone propiedades que corresponden a las variables globales que se han descrito anteriormente. 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.

Agregue el código siguiente a la clase MyControl1.

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 host

El componente final del archivo es la clase MyControlEventArgs, que se usa para devolver los datos recopilados al host.

Agregue el código siguiente al espacio de nombres MyControls. La implementación es sencilla, por lo que no se tratará más adelante.

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. La compilación generará un archivo DLL denominado MyControls.dll.

Implementar la aplicación host de Windows Forms

La aplicación host de Windows Forms usa un objeto ElementHost para hospedar el control compuesto de WPF. La aplicación controla el evento OnButtonClick para recibir los datos del control compuesto. La aplicación también tiene un conjunto de botones de opción que se pueden usar para modificar la apariencia del control. En la siguiente ilustración se muestra la aplicación.

En la imagen siguiente se muestra un control compuesto de WPF hospedado en una aplicación de Windows Forms

Captura de pantalla que muestra un control Avalon de hospedaje en Windows Forms.

Crear el proyecto

Para iniciar el proyecto:

  1. Inicie Visual Studio y abra el cuadro de diálogo Nuevo proyecto.

  2. En Visual C# y en la categoría de Windows, seleccione la plantilla Aplicación de Windows Forms.

  3. Asigne al nuevo proyecto el nombre de WFHost.

  4. Para la ubicación, especifique la misma carpeta de nivel superior que contiene el proyecto MyControls.

  5. Haga clic en Aceptar para crear el proyecto.

También deberá agregar referencias al archivo DLL que contiene MyControl1 y otros ensamblados.

  1. Haga clic con el botón derecho en el nombre del proyecto en el Explorador de soluciones y seleccione Agregar referencia.

  2. Haga clic en la pestaña Examinar y busque la carpeta que contiene MyControls.dll. En este tutorial, esta carpeta es MyControls\bin\Debug.

  3. Seleccione MyControls.dll y haga clic en Aceptar.

  4. Agregue referencias a los ensamblados siguientes.

    • PresentationCore

    • PresentationFramework

    • System.Xaml

    • WindowsBase

    • WindowsFormsIntegration

Implementar la interfaz de usuario de la aplicación

La interfaz de usuario de la aplicación de Windows Forms contiene varios controles para interactuar con el control compuesto de WPF.

  1. Abra Form1 en el Diseñador de Windows Forms.

  2. Amplíe el formulario para que quepan los controles.

  3. En la esquina superior derecha del formulario, agregue un control System.Windows.Forms.Panel para contener el control compuesto de WPF.

  4. Agregue los controles System.Windows.Forms.GroupBox siguientes al formulario.

    Nombre Texto
    groupBox1 Color de fondo
    groupBox2 Color de primer plano
    groupBox3 Tamaño de fuente
    groupBox4 Familia de fuentes
    groupBox5 Estilo de fuente
    groupBox6 Espesor de fuente
    groupBox7 Datos del control
  5. Agregue los controles System.Windows.Forms.RadioButton siguientes a los controles System.Windows.Forms.GroupBox.

    GroupBox Nombre Texto
    groupBox1 radioBackgroundOriginal Original
    groupBox1 radioBackgroundLightGreen LightGreen
    groupBox1 radioBackgroundLightSalmon LightSalmon
    groupBox2 radioForegroundOriginal Original
    groupBox2 radioForegroundRed Rojo
    groupBox2 radioForegroundYellow Amarillo
    groupBox3 radioSizeOriginal Original
    groupBox3 radioSizeTen 10
    groupBox3 radioSizeTwelve 12
    groupBox4 radioFamilyOriginal Original
    groupBox4 radioFamilyTimes Times New Roman
    groupBox4 radioFamilyWingDings WingDings
    groupBox5 radioStyleOriginal Normal
    groupBox5 radioStyleItalic Cursiva
    groupBox6 radioWeightOriginal Original
    groupBox6 radioWeightBold Bold
  6. Agregue los controles System.Windows.Forms.Label siguientes al último control System.Windows.Forms.GroupBox. Estos controles muestran los datos devueltos por el control compuesto de WPF.

    GroupBox Nombre Texto
    groupBox7 lblName Nombre:
    groupBox7 lblAddress Dirección postal:
    groupBox7 lblCity Ciudad:
    groupBox7 lblState Estado:
    groupBox7 lblZip Código postal:

Inicializar el formulario

El código de hospedaje se suele implementar en el controlador de eventos Load del formulario. En el código siguiente se muestra el controlador de eventos Load, un controlador para el evento Loaded del control compuesto de WPF y declaraciones de distintas variables globales que se usarán más adelante.

En el Diseñador de Windows Forms, haga doble clic en el formulario para crear el controlador de eventos Load. Al principio del archivo Form1.cs, agregue las instrucciones using siguientes.

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

Reemplace el contenido de la clase Form1 existente por el código siguiente.

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

En el método Form1_Load del código anterior se muestra el procedimiento general para hospedar un control de WPF:

  1. Cree un nuevo objeto ElementHost.

  2. Establezca la propiedad DockStyle.Fill del control en Dock.

  3. Agregue el control ElementHost a la colección Controls del control Panel.

  4. Cree una instancia del control de WPF.

  5. Para hospedar el control compuesto en el formulario, asígnelo a la propiedad Child del control ElementHost.

Las dos líneas restantes del método Form1_Load adjuntan controladores para dos eventos de control:

  • OnButtonClick es un evento personalizado que activa el control compuesto cuando el usuario hace clic en el botón Aceptar o Cancelar. El evento se controla para obtener la respuesta del usuario y recopilar los datos que este haya especificado.

  • Loaded es un evento estándar que genera un control de WPF cuando se carga de forma completa. El evento se usa aquí porque el ejemplo necesita inicializar distintas variables globales usando las propiedades del control. Cuando se produce el evento Load del formulario, el control no está totalmente cargado y esos valores todavía están establecidos en null. Debe esperar a que se genere el evento Loaded del control para poder acceder a esas propiedades.

El controlador de eventos Loaded se muestra en el código anterior. El controlador OnButtonClick se describe en la siguiente sección.

Administrar OnButtonClick

El evento OnButtonClick se produce cuando el usuario hace clic en el botón Aceptar o Cancelar.

El controlador de eventos comprueba el campo IsOK del argumento del evento para determinar en qué botón se ha hecho clic. Las variables lbldata se corresponden a los controles Label descritos antes. Si el usuario hace clic en el botón Aceptar, los datos de los controles TextBox del control se asignan al control Label correspondiente. Si el usuario hace clic en Cancelar, los valores Text se establecen en las cadenas predeterminadas.

Agregue el siguiente código de controlador de eventos de clic de botón a la clase Form1.

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. Agregue texto al control compuesto de WPF y, después, haga clic en Aceptar. El texto aparece en las etiquetas. En este momento, no se ha agregado código para controlar los botones de radio.

Modificar la apariencia del control

Los controles RadioButton del formulario permitirán al usuario cambiar el color de fondo y de primer plano del control compuesto de WPF, así como varias propiedades de fuente. El objeto ElementHost expone el color de fondo. Las propiedades restantes se exponen como propiedades personalizadas del control.

Haga doble clic en cada control RadioButton del formulario para crear controladores de eventos CheckedChanged. Reemplace los controladores de evento CheckedChanged con el código siguiente.

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. Haga clic en los diferentes botones de radio para ver el efecto en el control compuesto de WPF.

Vea también