Tutorial: Hospedar un control compuesto de formularios Windows Forms en Windows Presentation Foundation
Actualización: noviembre 2007
Windows Presentation Foundation (WPF) proporciona un entorno enriquecido para crear aplicaciones. Sin embargo, cuando se tiene una inversión sustancial en código de formularios Windows Forms, puede resultar más efectivo reutilizar al menos parte de ese código en la aplicación de WPF en lugar de volver a escribirlo todo desde el principio. El escenario más común es el caso en que ya existen controles personalizados de formularios Windows Forms. En algunos casos, puede que ni siquiera tenga acceso al código fuente de estos controles. WPF proporciona un procedimiento sencillo para hospedar estos controles en una aplicación de WPF. Por ejemplo, puede utilizar WPF para realizar la mayoría de la programación al hospedar los controles System.Windows.Forms.DataGridView especializados.
En este tutorial se crea paso a paso una aplicación que hospeda un control de formularios Windows Forms compuesto en una página de WPF. Este procedimiento general se puede hacer extensivo a aplicaciones y controles más complejos.
El tutorial está dividido en dos secciones. La primera sección describe brevemente la implementación del control de formularios Windows Forms. La segunda sección explica en detalle cómo hospedar el control en una aplicación de WPF, recibir eventos del control y obtener acceso a algunas de las propiedades del control.
Entre las tareas ilustradas en este tutorial se incluyen:
Implementar el control de formularios Windows Forms.
Implementar la aplicación host con Windows Presentation Foundation.
Para ver una lista de código completa de las tareas ilustradas en este tutorial, vea Ejemplo Hosting a Windows Forms Composite Control in Windows Presentation Foundation.
Requisitos previos
Necesita los componentes siguientes para completar este tutorial:
- Visual Studio 2008.
Implementar el control de formularios Windows Forms
El control de formularios Windows Forms utilizado en este ejemplo es un formulario de entrada de datos simple. Este formulario toma el nombre del usuario y su dirección y, a continuación, utiliza un evento personalizado para devolver esa información al host. En la siguiente ilustración se muestra el control representado.
Control de Windows Forms
Crear el proyecto
Para iniciar el proyecto:
Inicie Microsoft Visual Studio y abra el cuadro de diálogo Nuevo proyecto.
Seleccione Proyectos de C# con la plantilla Biblioteca de controles de Windows Forms.
Asigne al nuevo proyecto el nombre MyControls y haga clic en Aceptar para crear el proyecto. El proyecto predeterminado contiene un solo control cuyo nombre es UserControl1.
Cambie el nombre de UserControl1 a MyControl1.
El proyecto debe tener referencias a las siguientes DLL del sistema. Si cualquiera de estas DLL no está incluida de forma predeterminada, agréguela al proyecto.
System
System.Data
System.Drawing
System.Windows.Forms
System.XML
Agregar controles al formulario
Para agregar controles al formulario:
- Abra el diseñador de MyControl1.
Coloque en el formulario seis controles System.Windows.Forms.Label y sus controles System.Windows.Forms.TextBox correspondientes, con los tamaños y la organización indicados en la ilustración anterior. En el ejemplo, los controles TextBox tienen los nombres siguientes:
txtName
txtAddress
txtCity
txtState
txtZip
Agregue dos controles System.Windows.Forms.Button con las etiquetas Aceptar y Cancelar. En el ejemplo, los nombres de botón son btnOK y btnCancel, respectivamente.
Implementar el código de compatibilidad
Abra la vista de código del formulario. El control devuelve los datos recolectados al host provocando el evento OnButtonClick personalizado. Los datos están contenidos en el objeto de argumento de evento. En el siguiente código se muestra la declaración del evento y el delegado. Agregue este código al archivo de código, debajo del código generado por el diseñador.
Public Delegate Sub MyControlEventHandler(ByVal sender As Object, ByVal args As MyControlEventArgs)
Public Event OnButtonClick As MyControlEventHandler
public delegate void MyControlEventHandler(object sender, MyControlEventArgs args);
public event MyControlEventHandler OnButtonClick;
La clase MyControlEventArgs contiene la información que se devolverá al host. Agregue las clase siguiente al espacio de nombres del formulario.
Public Class MyControlEventArgs
Inherits EventArgs
Private _Name As String
Private _StreetAddress As String
Private _City As String
Private _State As String
Private _Zip As String
Private _IsOK As Boolean
Public Sub New(ByVal result As Boolean, ByVal name As String, ByVal address As String, ByVal city As String, ByVal state As String, ByVal zip As String)
_IsOK = result
_Name = name
_StreetAddress = address
_City = city
_State = state
_Zip = zip
End Sub
Public Property MyName() As String
Get
Return _Name
End Get
Set
_Name = value
End Set
End Property
Public Property MyStreetAddress() As String
Get
Return _StreetAddress
End Get
Set
_StreetAddress = value
End Set
End Property
Public Property MyCity() As String
Get
Return _City
End Get
Set
_City = value
End Set
End Property
Public Property MyState() As String
Get
Return _State
End Get
Set
_State = value
End Set
End Property
Public Property MyZip() As String
Get
Return _Zip
End Get
Set
_Zip = value
End Set
End Property
Public Property IsOK() As Boolean
Get
Return _IsOK
End Get
Set
_IsOK = value
End Set
End Property
End Class
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; }
}
}
Cuando el usuario hace clic en el botón Aceptar o Cancelar, los controladores del evento Control.Click crean un objeto MyControlEventArgs que contiene los datos y provoca el evento OnButtonClick. La única diferencia entre los dos controladores es la propiedad IsOK del argumento de evento. Esta propiedad permite al host determinar en qué botón se hizo clic. Se establece en true para el botón Aceptar y en false para el botón Cancelar. En el siguiente ejemplo de código se muestran los controladores de los dos botones. Agregue este código a la clase, debajo de la declaración de evento y de delegado mostrada en el primer ejemplo de código de esta sección.
Private Sub OKButton_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnOK.Click
Dim retvals As New MyControlEventArgs(True, txtName.Text, txtAddress.Text, txtCity.Text, txtState.Text, txtZip.Text)
RaiseEvent OnButtonClick(Me, retvals)
End Sub
Private Sub CancelButton_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnCancel.Click
Dim retvals As New MyControlEventArgs(False, txtName.Text, txtAddress.Text, txtCity.Text, txtState.Text, txtZip.Text)
RaiseEvent OnButtonClick(Me, retvals)
End Sub
End Class
private void OKButton_Click(object sender, System.EventArgs e)
{
MyControlEventArgs retvals = new MyControlEventArgs(true,
txtName.Text,
txtAddress.Text,
txtCity.Text,
txtState.Text,
txtZip.Text);
OnButtonClick(this, retvals);
}
private void CancelButton_Click(object sender, System.EventArgs e)
{
MyControlEventArgs retvals = new MyControlEventArgs(false,
txtName.Text,
txtAddress.Text,
txtCity.Text,
txtState.Text,
txtZip.Text);
OnButtonClick(this, retvals);
}
Dar un nombre seguro al ensamblado y generar el ensamblado
Para que una aplicación de WPF pueda hacer referencia a este ensamblado, debe tener un nombre seguro. Para crear un nombre seguro, cree un archivo de clave con Sn.exe y agréguelo al archivo AssemblyInfo.cs del proyecto.
Abra un símbolo del sistema de Visual Studio. Para ello, haga clic en el menú Inicio y seleccione Todos los programas/Microsoft Visual Studio 2008/Visual Studio Tools/Símbolo del sistema de Visual Studio 2008. Se iniciará una ventana de consola con variables de entorno personalizadas.
En el símbolo del sistema, utilice el comando "cd" para ir a la carpeta del proyecto.
Genere un archivo de clave con el nombre MyControls.snk ejecutando el comando siguiente.
Sn.exe -k MyControls.snk
Para incluir el archivo de clave en el proyecto, haga clic con el botón secundario en el nombre del proyecto en el Explorador de soluciones y abra el cuadro de diálogo Propiedades. Seleccione la ficha Firma y escriba el nombre de su archivo de clave.
Genere el ensamblado. La compilación generará una DLL denominada MyControls.dll.
Implementar la aplicación host con Windows Presentation Foundation
La aplicación host de WPF utiliza el control WindowsFormsHost para hospedar MyControl1. La aplicación controla el evento OnButtonClick para recibir los datos del control. También tiene una colección de botones de opción que permiten cambiar algunas de las propiedades del control desde la página de WPF. En la ilustración siguiente se muestra la aplicación acabada.
Aplicación completa, que muestra el control incrustado en la página de Windows Presentation Foundation
Crear el proyecto
Para iniciar el proyecto:
Abra Visual Studio y seleccione Nuevo proyecto.
Seleccione la plantilla Aplicación de explorador WPF.
Dé al proyecto el nombre WpfHost y haga clic en Aceptar para abrirlo.
También necesitará agregar una referencia a la DLL que contiene MyControl1. La manera más simple de agregar la referencia es la siguiente.
En el Explorador de soluciones, haga clic con el botón secundario en el nombre del proyecto y abra el cuadro de diálogo Agregar referencia.
Haga clic en la ficha Examinar y vaya a la carpeta de salida del control de Windows Forms. Para este ejemplo, esta carpeta es MyControls\bin\Debug.
Seleccione la DLL que contiene el control y haga clic en Aceptar para agregarlo a la lista de referencias. Para Ejemplo Hosting a Windows Forms Composite Control in Windows Presentation Foundation, esta DLL se denomina MyControls.dll.
En el Explorador de soluciones, agregue una referencia al ensamblado WindowsFormsIntegration, denominado WindowsFormsIntegration.dll.
Implementar el diseño básico
La interfaz de usuario (UI) de la aplicación host se implementa en Page1.xaml. Este archivo contiene el marcado de Lenguaje de marcado de aplicaciones extensible (XAML) que define el diseño de página y hospeda el control de formularios Windows Forms. La página está dividida en tres áreas:
El panel Control Properties (Propiedades del control), que contiene una colección de botones de opción que puede utilizar para modificar varias propiedades del control hospedado.
El panel Data from Control (Datos del control) que contiene varios elementos TextBlock que muestran los datos devueltos del control hospedado.
El propio control hospedado.
El código de diseño básico se muestra en el ejemplo de código siguiente. El código de marcado que se necesita para hospedar MyControl1 se omite en este ejemplo, pero se explicará más adelante. Reemplace el código de Page1.xaml por lo siguiente.
<Page xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
x:Class="Page1"
xmlns:mcl="clr-namespace:MyControls;assembly=MyControls"
Loaded="Init">
<DockPanel>
<DockPanel.Resources>
<Style x:Key="inlineText" TargetType="{x:Type Inline}">
<Setter Property="FontWeight" Value="Normal"/>
</Style>
<Style x:Key="titleText" TargetType="{x:Type TextBlock}">
<Setter Property="DockPanel.Dock" Value="Top"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="Margin" Value="10,5,10,0"/>
</Style>
</DockPanel.Resources>
<StackPanel Orientation="Vertical"
DockPanel.Dock="Left"
Background="Bisque"
Width="250">
<TextBlock Margin="10,10,10,10"
FontWeight="Bold"
FontSize="12">Control Properties</TextBlock>
<TextBlock Style="{StaticResource titleText}">Background Color</TextBlock>
<StackPanel Margin="10,10,10,10">
<RadioButton Name="rdbtnOriginalBackColor"
IsChecked="True"
Click="BackColorChanged">Original</RadioButton>
<RadioButton Name="rdbtnBackGreen"
Click="BackColorChanged">LightGreen</RadioButton>
<RadioButton Name="rdbtnBackSalmon"
Click="BackColorChanged">LightSalmon</RadioButton>
</StackPanel>
<TextBlock Style="{StaticResource titleText}">Foreground Color</TextBlock>
<StackPanel Margin="10,10,10,10">
<RadioButton Name="rdbtnOriginalForeColor"
IsChecked="True"
Click="ForeColorChanged">Original</RadioButton>
<RadioButton Name="rdbtnForeRed"
Click="ForeColorChanged">Red</RadioButton>
<RadioButton Name="rdbtnForeYellow"
Click="ForeColorChanged">Yellow</RadioButton>
</StackPanel>
<TextBlock Style="{StaticResource titleText}">Font Family</TextBlock>
<StackPanel Margin="10,10,10,10">
<RadioButton Name="rdbtnOriginalFamily"
IsChecked="True"
Click="FontChanged">Original</RadioButton>
<RadioButton Name="rdbtnTimes"
Click="FontChanged">Times New Roman</RadioButton>
<RadioButton Name="rdbtnWingdings"
Click="FontChanged">Wingdings</RadioButton>
</StackPanel>
<TextBlock Style="{StaticResource titleText}">Font Size</TextBlock>
<StackPanel Margin="10,10,10,10">
<RadioButton Name="rdbtnOriginalSize"
IsChecked="True"
Click="FontSizeChanged">Original</RadioButton>
<RadioButton Name="rdbtnTen"
Click="FontSizeChanged">10</RadioButton>
<RadioButton Name="rdbtnTwelve"
Click="FontSizeChanged">12</RadioButton>
</StackPanel>
<TextBlock Style="{StaticResource titleText}">Font Style</TextBlock>
<StackPanel Margin="10,10,10,10">
<RadioButton Name="rdbtnNormalStyle"
IsChecked="True"
Click="StyleChanged">Original</RadioButton>
<RadioButton Name="rdbtnItalic"
Click="StyleChanged">Italic</RadioButton>
</StackPanel>
<TextBlock Style="{StaticResource titleText}">Font Weight</TextBlock>
<StackPanel Margin="10,10,10,10">
<RadioButton Name="rdbtnOriginalWeight"
IsChecked="True"
Click="WeightChanged">
Original
</RadioButton>
<RadioButton Name="rdbtnBold"
Click="WeightChanged">Bold</RadioButton>
</StackPanel>
</StackPanel>
<WindowsFormsHost Name="wfh"
DockPanel.Dock="Top"
Height="300">
<mcl:MyControl1 Name="mc"/>
</WindowsFormsHost>
<StackPanel Orientation="Vertical"
Height="Auto"
Background="LightBlue">
<TextBlock Margin="10,10,10,10"
FontWeight="Bold"
FontSize="12">Data From Control</TextBlock>
<TextBlock Style="{StaticResource titleText}">
Name: <Span Name="txtName" Style="{StaticResource inlineText}"/>
</TextBlock>
<TextBlock Style="{StaticResource titleText}">
Street Address: <Span Name="txtAddress" Style="{StaticResource inlineText}"/>
</TextBlock>
<TextBlock Style="{StaticResource titleText}">
City: <Span Name="txtCity" Style="{StaticResource inlineText}"/>
</TextBlock>
<TextBlock Style="{StaticResource titleText}">
State: <Span Name="txtState" Style="{StaticResource inlineText}"/>
</TextBlock>
<TextBlock Style="{StaticResource titleText}">
Zip: <Span Name="txtZip" Style="{StaticResource inlineText}"/>
</TextBlock>
</StackPanel>
</DockPanel>
</Page>
<Page xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
x:Class="WpfHost.Page1"
xmlns:mcl="clr-namespace:MyControls;assembly=MyControls"
Loaded="Init">
<DockPanel>
<DockPanel.Resources>
<Style x:Key="inlineText" TargetType="{x:Type Inline}">
<Setter Property="FontWeight" Value="Normal"/>
</Style>
<Style x:Key="titleText" TargetType="{x:Type TextBlock}">
<Setter Property="DockPanel.Dock" Value="Top"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="Margin" Value="10,5,10,0"/>
</Style>
</DockPanel.Resources>
<StackPanel Orientation="Vertical"
DockPanel.Dock="Left"
Background="Bisque"
Width="250">
<TextBlock Margin="10,10,10,10"
FontWeight="Bold"
FontSize="12">Control Properties</TextBlock>
<TextBlock Style="{StaticResource titleText}">Background Color</TextBlock>
<StackPanel Margin="10,10,10,10">
<RadioButton Name="rdbtnOriginalBackColor"
IsChecked="True"
Click="BackColorChanged">Original</RadioButton>
<RadioButton Name="rdbtnBackGreen"
Click="BackColorChanged">LightGreen</RadioButton>
<RadioButton Name="rdbtnBackSalmon"
Click="BackColorChanged">LightSalmon</RadioButton>
</StackPanel>
<TextBlock Style="{StaticResource titleText}">Foreground Color</TextBlock>
<StackPanel Margin="10,10,10,10">
<RadioButton Name="rdbtnOriginalForeColor"
IsChecked="True"
Click="ForeColorChanged">Original</RadioButton>
<RadioButton Name="rdbtnForeRed"
Click="ForeColorChanged">Red</RadioButton>
<RadioButton Name="rdbtnForeYellow"
Click="ForeColorChanged">Yellow</RadioButton>
</StackPanel>
<TextBlock Style="{StaticResource titleText}">Font Family</TextBlock>
<StackPanel Margin="10,10,10,10">
<RadioButton Name="rdbtnOriginalFamily"
IsChecked="True"
Click="FontChanged">Original</RadioButton>
<RadioButton Name="rdbtnTimes"
Click="FontChanged">Times New Roman</RadioButton>
<RadioButton Name="rdbtnWingdings"
Click="FontChanged">Wingdings</RadioButton>
</StackPanel>
<TextBlock Style="{StaticResource titleText}">Font Size</TextBlock>
<StackPanel Margin="10,10,10,10">
<RadioButton Name="rdbtnOriginalSize"
IsChecked="True"
Click="FontSizeChanged">Original</RadioButton>
<RadioButton Name="rdbtnTen"
Click="FontSizeChanged">10</RadioButton>
<RadioButton Name="rdbtnTwelve"
Click="FontSizeChanged">12</RadioButton>
</StackPanel>
<TextBlock Style="{StaticResource titleText}">Font Style</TextBlock>
<StackPanel Margin="10,10,10,10">
<RadioButton Name="rdbtnNormalStyle"
IsChecked="True"
Click="StyleChanged">Original</RadioButton>
<RadioButton Name="rdbtnItalic"
Click="StyleChanged">Italic</RadioButton>
</StackPanel>
<TextBlock Style="{StaticResource titleText}">Font Weight</TextBlock>
<StackPanel Margin="10,10,10,10">
<RadioButton Name="rdbtnOriginalWeight"
IsChecked="True"
Click="WeightChanged">
Original
</RadioButton>
<RadioButton Name="rdbtnBold"
Click="WeightChanged">Bold</RadioButton>
</StackPanel>
</StackPanel>
<WindowsFormsHost Name="wfh"
DockPanel.Dock="Top"
Height="300">
<mcl:MyControl1 Name="mc"/>
</WindowsFormsHost>
<StackPanel Orientation="Vertical"
Height="Auto"
Background="LightBlue">
<TextBlock Margin="10,10,10,10"
FontWeight="Bold"
FontSize="12">Data From Control</TextBlock>
<TextBlock Style="{StaticResource titleText}">
Name: <Span Name="txtName" Style="{StaticResource inlineText}"/>
</TextBlock>
<TextBlock Style="{StaticResource titleText}">
Street Address: <Span Name="txtAddress" Style="{StaticResource inlineText}"/>
</TextBlock>
<TextBlock Style="{StaticResource titleText}">
City: <Span Name="txtCity" Style="{StaticResource inlineText}"/>
</TextBlock>
<TextBlock Style="{StaticResource titleText}">
State: <Span Name="txtState" Style="{StaticResource inlineText}"/>
</TextBlock>
<TextBlock Style="{StaticResource titleText}">
Zip: <Span Name="txtZip" Style="{StaticResource inlineText}"/>
</TextBlock>
</StackPanel>
</DockPanel>
</Page>
El primer elemento StackPanel contiene varios conjuntos de controles RadioButton que permiten modificar diversas propiedades predeterminadas del control hospedado. A continuación, hay un elemento WindowsFormsHost en el que se hospeda MyControl1. El último elemento StackPanel contiene varios elementos TextBlock que muestran los datos devueltos por el control hospedado. El orden de los elementos y los valores de atributo de Dock y Height incrustan el control hospedado en la página sin dejar espacios en blanco ni provocar distorsión.
Hospedar el control
La versión editada siguiente del ejemplo de código anterior se centra en los elementos que se necesitan para hospedar MyControl1.
<Page xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
x:Class="Page1"
xmlns:mcl="clr-namespace:MyControls;assembly=MyControls"
Loaded="Init">
...
<WindowsFormsHost Name="wfh"
DockPanel.Dock="Top"
Height="300">
<mcl:MyControl1 Name="mc"/>
</WindowsFormsHost>
<Page xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
x:Class="WpfHost.Page1"
xmlns:mcl="clr-namespace:MyControls;assembly=MyControls"
Loaded="Init">
...
<WindowsFormsHost Name="wfh"
DockPanel.Dock="Top"
Height="300">
<mcl:MyControl1 Name="mc"/>
</WindowsFormsHost>
Los atributos de asignación del espacio de nombres xmlns crean una referencia al espacio de nombres MyControls que contiene el control hospedado. Esta asignación permite representar MyControl1 en XAML como <mcl:MyControl1>.
Dos elementos del ejemplo de código administran el hospedaje:
WindowsFormsHost representa el elemento WindowsFormsHost que permite hospedar un control de formularios Windows Forms en una página de WPF.
mcl:MyControl1, que representa a MyControl1, se agrega a la colección de elementos secundarios del elemento WindowsFormsHost. Como resultado, este control de formularios Windows Forms se representa como parte de la página de WPF y es posible comunicarse con el control desde la página.
Implementar el archivo de código subyacente
El archivo de código subyacente, Page1.xaml.cs, contiene el código de procedimiento que implementa la funcionalidad de la interfaz de usuario descrita en la sección anterior. Las principales tareas son:
Asociar un controlador al evento OnButtonClick de MyControl1.
Modificar diversas propiedades de MyControl1, basándose en cómo se establezca la colección de botones de opción.
Mostrar los datos recolectados por el control.
Inicializar la aplicación
El código de inicialización está contenido en un controlador para el evento Loaded de la página y asocia un controlador al evento OnButtonClick del control. Copie el código siguiente en la clase Page1 de Page1.xaml.cs.
Class Page1
Inherits Page
Private app As Application
Private myWindow As NavigationWindow
Private initFontWeight As FontWeight
Private initFontSize As [Double]
Private initFontStyle As FontStyle
Private initBackBrush As SolidColorBrush
Private initForeBrush As SolidColorBrush
Private initFontFamily As FontFamily
Private UIIsReady As Boolean = False
Private Sub Init(ByVal sender As Object, ByVal e As RoutedEventArgs)
app = System.Windows.Application.Current
myWindow = CType(app.MainWindow, NavigationWindow)
myWindow.SizeToContent = SizeToContent.WidthAndHeight
wfh.TabIndex = 10
initFontSize = wfh.FontSize
initFontWeight = wfh.FontWeight
initFontFamily = wfh.FontFamily
initFontStyle = wfh.FontStyle
initBackBrush = CType(wfh.Background, SolidColorBrush)
initForeBrush = CType(wfh.Foreground, SolidColorBrush)
Dim mc As MyControl1 = wfh.Child
AddHandler mc.OnButtonClick, AddressOf Pane1_OnButtonClick
UIIsReady = True
End Sub
public partial class Page1 : Page
{
private Application app;
private NavigationWindow myWindow;
FontWeight initFontWeight;
Double initFontSize;
FontStyle initFontStyle;
SolidColorBrush initBackBrush;
SolidColorBrush initForeBrush;
FontFamily initFontFamily;
bool UIIsReady = false;
private void Init(object sender, EventArgs e)
{
app = System.Windows.Application.Current;
myWindow = (NavigationWindow)app.MainWindow;
myWindow.SizeToContent = SizeToContent.WidthAndHeight;
wfh.TabIndex = 10;
initFontSize = wfh.FontSize;
initFontWeight = wfh.FontWeight;
initFontFamily = wfh.FontFamily;
initFontStyle = wfh.FontStyle;
initBackBrush = (SolidColorBrush)wfh.Background;
initForeBrush = (SolidColorBrush)wfh.Foreground;
(wfh.Child as MyControl1).OnButtonClick += new MyControl1.MyControlEventHandler(Pane1_OnButtonClick);
UIIsReady = true;
}
Dado que en el código XAML descrito anteriormente se ha agregado MyControl1 a la colección de elementos secundarios del elemento WindowsFormsHost, puede convertir la propiedad Child del elemento WindowsFormsHost para obtener la referencia a MyControl1. A continuación, puede utilizar esa referencia para asociar un controlador de eventos a OnButtonClick.
Además de proporcionar una referencia al propio control, WindowsFormsHost expone varias propiedades del control, que puede manipular desde la página. En el código de inicialización se asignan esos valores a las variables globales privadas para su uso posterior en la aplicación.
Controlar el evento OnButtonClick
MyControl1 provoca el evento OnButtonClick cuando el usuario hace clic en cualquiera de los botones del control. Agregue el código siguiente a la clase Page1.
'Handle button clicks on the Windows Form control
Private Sub Pane1_OnButtonClick(ByVal sender As Object, ByVal args As MyControlEventArgs)
txtName.Inlines.Clear()
txtAddress.Inlines.Clear()
txtCity.Inlines.Clear()
txtState.Inlines.Clear()
txtZip.Inlines.Clear()
If args.IsOK Then
txtName.Inlines.Add(" " + args.MyName)
txtAddress.Inlines.Add(" " + args.MyStreetAddress)
txtCity.Inlines.Add(" " + args.MyCity)
txtState.Inlines.Add(" " + args.MyState)
txtZip.Inlines.Add(" " + args.MyZip)
End If
End Sub
End Class
//Handle button clicks on the Windows Form control
private void Pane1_OnButtonClick(object sender, MyControlEventArgs args)
{
txtName.Inlines.Clear();
txtAddress.Inlines.Clear();
txtCity.Inlines.Clear();
txtState.Inlines.Clear();
txtZip.Inlines.Clear();
if (args.IsOK)
{
txtName.Inlines.Add( " " + args.MyName );
txtAddress.Inlines.Add( " " + args.MyStreetAddress );
txtCity.Inlines.Add( " " + args.MyCity );
txtState.Inlines.Add( " " + args.MyState );
txtZip.Inlines.Add( " " + args.MyZip );
}
}
Los datos de los cuadros de texto se empaquetan en el objeto MyControlEventArgs. Si el usuario hace clic en el botón Aceptar botón, el controlador de eventos extrae los datos y los muestra en el panel situado debajo de MyControl1.
Modificar las propiedades del control
El elemento WindowsFormsHost expone algunas de las propiedades predeterminadas de control hospedado. Como resultado, puede cambiar el aspecto del control para adaptarlo mejor al estilo de la página. Los conjuntos de botones de opción del panel izquierdo permiten al usuario modificar varias propiedades de color y fuente. Cada conjunto de botones tiene un controlador para el evento Click, que detecta qué botón selecciona el usuario y cambia la propiedad correspondiente del control. Copie el código siguiente a la clase Page1. Ahora puede generar y ejecutar la aplicación.
Private Sub BackColorChanged(ByVal sender As Object, ByVal e As RoutedEventArgs)
If sender.Equals(rdbtnBackGreen) Then
wfh.Background = New SolidColorBrush(Colors.LightGreen)
ElseIf sender.Equals(rdbtnBackSalmon) Then
wfh.Background = New SolidColorBrush(Colors.LightSalmon)
ElseIf UIIsReady = True Then
wfh.Background = initBackBrush
End If
End Sub
Private Sub ForeColorChanged(ByVal sender As Object, ByVal e As RoutedEventArgs)
If sender.Equals(rdbtnForeRed) Then
wfh.Foreground = New SolidColorBrush(Colors.Red)
ElseIf sender.Equals(rdbtnForeYellow) Then
wfh.Foreground = New SolidColorBrush(Colors.Yellow)
ElseIf UIIsReady = True Then
wfh.Foreground = initForeBrush
End If
End Sub
Private Sub FontChanged(ByVal sender As Object, ByVal e As RoutedEventArgs)
If sender.Equals(rdbtnTimes) Then
wfh.FontFamily = New FontFamily("Times New Roman")
ElseIf sender.Equals(rdbtnWingdings) Then
wfh.FontFamily = New FontFamily("Wingdings")
ElseIf UIIsReady = True Then
wfh.FontFamily = initFontFamily
End If
End Sub
Private Sub FontSizeChanged(ByVal sender As Object, ByVal e As RoutedEventArgs)
If sender.Equals(rdbtnTen) Then
wfh.FontSize = 10
ElseIf sender.Equals(rdbtnTwelve) Then
wfh.FontSize = 12
ElseIf UIIsReady = True Then
wfh.FontSize = initFontSize
End If
End Sub
Private Sub StyleChanged(ByVal sender As Object, ByVal e As RoutedEventArgs)
If sender.Equals(rdbtnItalic) Then
wfh.FontStyle = FontStyles.Italic
ElseIf UIIsReady = True Then
wfh.FontStyle = initFontStyle
End If
End Sub
Private Sub WeightChanged(ByVal sender As Object, ByVal e As RoutedEventArgs)
If sender.Equals(rdbtnBold) Then
wfh.FontWeight = FontWeights.Bold
ElseIf UIIsReady = True Then
wfh.FontWeight = initFontWeight
End If
End Sub
private void BackColorChanged(object sender, RoutedEventArgs e)
{
if (sender == rdbtnBackGreen)
wfh.Background = new SolidColorBrush(Colors.LightGreen);
else if (sender == rdbtnBackSalmon)
wfh.Background = new SolidColorBrush(Colors.LightSalmon);
else if (UIIsReady == true)
wfh.Background = initBackBrush;
}
private void ForeColorChanged(object sender, RoutedEventArgs e)
{
if (sender == rdbtnForeRed)
wfh.Foreground = new SolidColorBrush(Colors.Red);
else if (sender == rdbtnForeYellow)
wfh.Foreground = new SolidColorBrush(Colors.Yellow);
else if (UIIsReady == true)
wfh.Foreground = initForeBrush;
}
private void FontChanged(object sender, RoutedEventArgs e)
{
if (sender == rdbtnTimes)
wfh.FontFamily = new FontFamily("Times New Roman");
else if (sender == rdbtnWingdings)
wfh.FontFamily = new FontFamily("Wingdings");
else if (UIIsReady == true)
wfh.FontFamily = initFontFamily;
}
private void FontSizeChanged(object sender, RoutedEventArgs e)
{
if (sender == rdbtnTen)
wfh.FontSize = 10;
else if (sender == rdbtnTwelve)
wfh.FontSize = 12;
else if (UIIsReady == true)
wfh.FontSize = initFontSize;
}
private void StyleChanged(object sender, RoutedEventArgs e)
{
if (sender == rdbtnItalic)
wfh.FontStyle = FontStyles.Italic;
else if (UIIsReady == true)
wfh.FontStyle = initFontStyle;
}
private void WeightChanged(object sender, RoutedEventArgs e)
{
if (sender == rdbtnBold)
wfh.FontWeight = FontWeights.Bold;
else if (UIIsReady == true)
wfh.FontWeight = initFontWeight;
}
Vea también
Tareas
Tutorial: Hospedar un control de formularios Windows Forms en Windows Presentation Foundation
Conceptos
Tutorial: Hospedar un control de Windows Presentation Foundation en formularios Windows Forms