¿Le resultó útil esta página?
Sus comentarios sobre este contenido son muy importantes. Háganos saber su opinión.
¿Tiene comentarios adicionales?
Caracteres restantes: 1500
Exportar (0) Imprimir
Expandir todo
Este artículo se tradujo de forma manual. Mueva el puntero sobre las frases del artículo para ver el texto original.
Traducción
Original

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

Windows Presentation Foundation (WPF) proporciona un entorno enriquecido para crear aplicaciones. Sin embargo, cuando se tiene una inversión sustancial en código Windows Forms, puede ser más efectivo extender la aplicación Windows Forms existente con WPF en lugar de rescribirla desde el principio. Un escenario común se da cuando se desea incrustar uno o varios controles implementados con WPF dentro de una aplicación de Windows Forms. Para obtener más información sobre cómo personalizar los controles de WPF, vea Personalización de controles.

Este tutorial describe 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 una DLL. Este procedimiento general se puede hacer extensivo a aplicaciones y controles más complejos. Este tutorial se ha diseñado para que sea casi idéntico en aspecto y funcionalidad a Tutorial: Hospedar un control compuesto de formularios Windows Forms en WPF. La diferencia principal es que se invierte el escenario de hospedaje.

El tutorial está dividido en dos secciones. La primera sección describe brevemente la implementación del control compuesto de WPF. La segunda sección explica en detalle cómo hospedar el control compuesto en una aplicación de Windows Forms, recibir eventos del control y obtener acceso 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 formularios de Windows Forms.

Para ver una lista de código completa de las tareas mostradas en este tutorial, vea Hosting a WPF Composite Control in Windows Forms Sample.

Necesita los componentes siguientes para completar este tutorial:

  • Visual Studio 2010.

El control compuesto de WPF utilizado 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 compuesto genera un evento personalizado para devolver esa información al host. En la siguiente ilustración se muestra el control representado.

Control compuesto de WPF

Control simple de WPF

Crear el proyecto

Para iniciar el proyecto:

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

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

  3. Denomine el nuevo proyecto MyControls.

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

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

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

El proyecto debe tener referencias a las siguientes DLL del sistema. Si cualquiera de estas DLL no se incluye de forma predeterminada, agréguela al proyecto.

  • PresentationCore

  • PresentationFramework

  • Sistema

  • WindowsBase

Crear la interfaz de usuario

El elemento user interface (UI) del control compuesto se implementa mediante Extensible Application Markup Language (XAML). El control compuesto UI consta de cinco elementos TextBox. Cada elemento TextBox tiene un elemento TextBlock asociado que actúa como una etiqueta. Hay dos elementos Button en la parte inferior, 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 diversos elementos UI se contienen en un elemento Grid. Puede utilizar Grid para organizar el contenido del control compuesto de manera muy similar a como utilizaría un elemento Table en HTML. WPF también tiene un elemento Table, pero Grid es más ligero y más adecuado para las tareas sencillas de diseño.

El siguiente código XAML muestra el diseño básico. Este código XAML define la estructura global del control especificando el número de columnas y filas del elemento Grid.

En MyControl1.xaml, reemplace el XAML existente por el siguiente 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 UI en la cuadrícula, establezca los atributos RowProperty y ColumnProperty en los números de fila y columna correspondientes. Recuerde que la numeración de filas y columnas está basada en cero. Puede hacer que un elemento abarque varias columnas estableciendo su atributo ColumnSpanProperty. Para obtener más información sobre los elementos Grid, vea Cómo: Crear un elemento Grid.

El siguiente XAML muestra los elementos TextBox y TextBlock del control compuesto con sus atributos RowProperty y ColumnProperty, que se establecen para colocar correctamente los elementos en la cuadrícula.

En MyControl1.xaml, agregue el siguiente XAML 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 la 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 los atributos de cada elemento de forma independiente, el XAML anterior utiliza elementos Style para definir los valores estándar de las propiedades para las clases de elementos. Este enfoque reduce la complejidad del control y permite cambiar el aspecto de varios elementos a través de un atributo de estilo único.

Los elementos Style se incluyen en la propiedad Resources del elemento Grid, por lo que pueden ser utilizados por todos los elementos del control. Si un estilo tiene nombre, puede aplicarlo a un elemento agregando un elemento Style establecido en el nombre del estilo. Los estilos que no tienen nombre se convierten en el estilo predeterminado del elemento. Para obtener más información acerca de los estilos de WPF, vea Aplicar estilos y plantillas.

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

En MyControl1.xaml, agregue el siguiente XAML 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 Aceptar y CancelarButton, que ocupan las primeras dos columnas de la última fila del elemento Grid. Estos elementos utilizan un controlador de eventos común, ButtonClicked y el estilo Button predeterminado definido en el código XAML anterior.

En MyControl1.xaml, agregue el siguiente XAML justo después del último elemento TextBox. El componente XAML del control compuesto está ahora completo.


<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 lo empaqueta en un objeto de argumento de evento personalizado.

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

El control también expone diversas propiedades de color y fuente que permiten cambiar el aspecto. A diferencia de la clase WindowsFormsHost, que se utiliza para hospedar un control Windows Forms, la clase ElementHost solamente expone la propiedad Background del control. Para mantener la similitud entre este ejemplo de código y el ejemplo explicado en Tutorial: Hospedar un control compuesto de formularios 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 contendrá dos clases, MyControl1 y 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 UI definida en MyControl1.xaml. Cuando se analiza MyControl1.xaml, el XAML se convierte en la misma clase parcial y las dos clases parciales se combinan para formar el control compilado. Por esta razón, 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 utiliza para devolver los datos al host.

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


public partial class MyControl1 : Grid


Inicializar el control

El siguiente código implementa varias tareas básicas:

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

  • Crea varias 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 asignándoles los valores definidos en MyControl1.xaml. Utiliza para ello la propiedad Name asignada a un elemento TextBlock típico, nameLabel, para tener acceso a los valores de las propiedades 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 finaliza haciendo clic en el botón Aceptar o en el botón Cancelar. Ambos botones utilizan el mismo controlador de eventos Click, ButtonClicked. Ambos botones tienen un nombre, btnOK o btnCancel, que permite al controlador determinar en qué botón se hizo clic examinando el valor del argumento sender. El controlador hace lo siguiente:

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

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

  • Provoca 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 explicadas anteriormente. Cuando una propiedad cambia, 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 último componente del archivo es la clase MyControlEventArgs, que se utiliza para devolver los datos recopilados al host.

Agregue el código siguiente al espacio de nombres MyControls. La implementación es sencilla y no se ofrece ninguna otra explicación.


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á una DLL denominada MyControls.dll.

La aplicación host de Windows Forms utiliza 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 puede utilizar para modificar el aspecto del control. En la ilustración siguiente se muestra la aplicación.

El control compuesto de WPF hospedado en una aplicación de Windows Forms

Control Avalon de hospedaje en un formulario 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 la categoría de Windows, seleccione la plantilla Aplicación de Windows Forms.

  3. Denomine el nuevo proyecto 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 debe agregar referencias a la DLL que contiene MyControl1 y a otros ensamblados.

  1. En el Explorador de soluciones, haga clic con el botón secundario del mouse en el nombre del proyecto y seleccione Agregar referencia.

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

  3. Seleccione MyControls.dll y, a continuación, haga clic en Aceptar.

  4. Agregue referencias a los siguientes ensamblados.

    • 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 alojar los controles.

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

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

    Nombre

    Text

    groupBox1

    Color de fondo

    groupBox2

    Color de primer plano

    groupBox3

    FontSize

    groupBox4

    Familia de fuentes

    groupBox5

    Estilo de fuente

    groupBox6

    Grosor de fuente

    groupBox7

    Datos del control

  5. Agregue los siguientes controles System.Windows.Forms.RadioButton a los controles System.Windows.Forms.GroupBox.

    GroupBox

    Nombre

    Text

    groupBox1

    radioBackgroundOriginal

    Original

    groupBox1

    radioBackgroundLightGreen

    LightGreen

    groupBox1

    radioBackgroundLightSalmon

    LightSalmon

    groupBox2

    radioForegroundOriginal

    Original

    groupBox2

    radioForegroundRed

    Red

    groupBox2

    radioForegroundYellow

    Yellow

    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

    Negrita

  6. Agregue los siguientes controles System.Windows.Forms.Label al último System.Windows.Forms.GroupBox. Estos controles muestran los datos devueltos por el control compuesto de WPF.

    GroupBox

    Nombre

    Text

    groupBox7

    lblName

    Nombre:

    groupBox7

    lblAddress

    Dirección:

    groupBox7

    lblCity

    Ciudad:

    groupBox7

    lblState

    Estado:

    groupBox7

    lblZip

    Código postal:

Inicializar el formulario

Generalmente, implementará el código host en el controlador de eventos Load del formulario. El código siguiente muestra el controlador de eventos Load, un controlador del evento Loaded del control compuesto de WPF y las declaraciones de varias variables globales que se utilizarán más adelante.

En el Diseñador de Windows Forms, haga doble clic en el formulario para crear un controlador de eventos Load. En la parte superior de Form1.cs, agregue las siguientes instrucciones using.


using System;
using System.Windows;
using System.Windows.Navigation;
using System.Windows.Controls;
using System.Windows.Media;

namespace MyControls
{
    public partial class MyControl1 : Grid
    {
        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;
        }

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

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

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



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


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


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 método Form1_Load del código anterior muestra el procedimiento general para hospedar un control WPF:

  1. Crear un nuevo objeto ElementHost.

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

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

  4. Cree una instancia del control de WPF.

  5. Hospede el control compuesto en el formulario asignando el control a la propiedad Child del control ElementHost.

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

  • OnButtonClick es un evento personalizado iniciado por el control compuesto cuando el usuario hace clic en el botón Aceptar o Cancelar. Controle el evento para obtener la respuesta del usuario y recopilar cualquier dato que especifique el usuario.

  • Loaded es un evento estándar generado por un control de WPF cuando se carga totalmente. El evento se utiliza aquí porque el ejemplo debe inicializar varias variables globales utilizando propiedades del control. En el momento del evento Load del formulario, el control no está cargado totalmente y esos valores todavía están establecidos en null. Debe esperar hasta que se produzca el evento Loaded del control para poder tener acceso a esas propiedades.

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

Administrar OnButtonClick

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

El controlador de eventos consulte el campo IsOK del argumento de evento para determinar en qué botón se hizo clic. Las variables lbldatos corresponden a los controles Label explicados anteriormente. 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: ";
    }
}


Genere y ejecute la aplicación. Agregue texto en el control compuesto de WPF y, a continuación, haga clic en Aceptar. El texto aparece en las etiquetas. En este punto, 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 los colores de fondo y primer plano del control compuesto de WPF, así como diversas 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 en el formulario para crear controladores de eventos CheckedChanged. Reemplace los controladores de eventos CheckedChanged por el siguiente código.


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


Genere y ejecute la aplicación. Haga clic en los distintos botones de radio para ver el efecto en el control compuesto de WPF.

Adiciones de comunidad

AGREGAR
Mostrar:
© 2015 Microsoft