Вы находитесь на странице: 1из 169

TUTORIALES DE WPF DESIGNER

Tutorial: Compilar una aplicación de


WPF sencilla con WPF Designer
En este tutorial realizará las siguientes tareas:
 Crear el proyecto.
 Crear el diseño.
 Agregar controles al diseño.
 Establecer las propiedades relacionadas con el diseño.
 Crear un origen de datos.
 Conectar con un origen de datos.
 Enlazar las propiedades de los controles.
Cuando haya finalizado, tendrá una aplicación que le permitirá examinar el sistema de
archivos. La interfaz de usuario de la aplicación se implementará en lenguaje
XAML.Para obtener más información, vea XAML en WPF. En la ilustración siguiente se
muestra la apariencia que tendrá la aplicación.
Note

Encontrará una versión de los laboratorios de prácticas de este tutorial que se


ejecuta en en el sitio WPF Simple Application Walkthrough Hands on Lab.

Requisitos previos
Necesita los componentes siguientes para completar este tutorial:

Crear el proyecto
El primer paso consiste en crear el proyecto para la aplicación.
Para crear el proyecto
1. Cree un nuevo proyecto de aplicación de WPF en Visual Basic o en Visual C#
denominado FolderExplorer. Para obtener más información, vea Cómo: Crear
un nuevo proyecto de aplicación de WPF.
MainWindow.xaml se abrirá en WPF Designer.
2. En la Vista de diseño, seleccione la ventana. Para obtener más información,
vea Cómo: Seleccionar y mover elementos en la superficie de diseño.
3. En la ventana Propiedades, establezca el valor de la propiedad Title en Folder
Explorer.

Crear el diseño
El diseño define cómo se organizan los controles en la ventana principal de la
aplicación. En los pasos siguientes se muestra cómo construir los elementos de diseño
que contendrán los controles de la aplicación.
Para crear el diseño
1. Seleccione el control Grid raíz en la ventana.
2. Agregue una segunda fila a la cuadrícula. Para obtener más información, vea
Cómo: Agregar filas y columnas a una cuadrícula.
3. Agregue una segunda columna a la cuadrícula.

Agregar controles al diseño


Una vez definido el diseño, puede rellenarlo con controles.
Para agregar controles al diseño
1. Desde el Cuadro de herramientas, arrastre un control TreeView a la primera
celda de la cuadrícula.
2. En el Cuadro de herramientas, arrastre un control ListView a la celda que
ocupa la primera fila y segunda columna de la cuadrícula.
3. En el Cuadro de herramientas, arrastre un control ListView a la celda que
ocupa la segunda fila y segunda columna de la cuadrícula.

Establecer las propiedades relacionadas con el


diseño
En los pasos siguientes se muestra cómo establecer las propiedades de los controles
relacionadas con el diseño. Al establecer las propiedades de cada control, el diseño va
pareciéndose cada vez más a la aplicación final.
Para establecer las propiedades relacionadas con el diseño
1. Seleccione el control TreeView.
2. En la ventana Propiedades, establezca las propiedades siguientes tal y como
se indica.

Propiedad. Valor

Grid.ColumnSpan 1

Grid.RowSpan 2

Alto Auto

HorizontalAlignment Stretch

Margin 0,0,0,0

VerticalAlignment Stretch

Ancho Auto
3. El control TreeView cambia de tamaño para ajustarse a la primera columna de
la cuadrícula y abarcar las dos filas de esta última.
4. Seleccione los dos controles ListView.
5. En la ventana Propiedades, establezca las propiedades siguientes tal y como
se indica.

Propiedad. Valor

Grid.ColumnSpan 1

Grid.RowSpan 1

Alto Auto

HorizontalAlignment Stretch

Margin 0,0,0,0

VerticalAlignment Stretch

Ancho Auto
6. Los controles ListView cambian de tamaño para ajustarse a sus celdas
respectivas de la cuadrícula.

7.
8. Abra la ventana Esquema del documento. Para obtener más información, vea
Navegar en la jerarquía de elementos de un documento de WPF.
9. Expanda el nodo ColumnDefinitions de la cuadrícula.
10. Seleccione el primer elemento ColumnDefinition.

11. En la ventana Propiedades, establezca la propiedad Width en *.


12. En la ventana Esquema del documento, seleccione el segundo elemento
ColumnDefinition.
13. En la ventana Propiedades, establezca la propiedad Width en 2*.
Se ajustará el tamaño de las columnas de modo que la primera ocupe la
tercera parte del ancho de la ventana y la segunda, dos tercios.
14. En la ventana Esquema del documento, expanda el nodo RowDefinitions de
la cuadrícula.
15. Seleccione el primer elemento RowDefinition.
16. En la ventana Propiedades, establezca la propiedad Height en *.
17. En la ventana Esquema del documento, seleccione el segundo elemento
RowDefinition.
18. En la ventana Propiedades, establezca la propiedad Height en *.
Se ajustará el tamaño de las filas de modo que ocupen la mitad del alto de la
ventana.
19. Compile y ejecute la solución.
20. Cambie el tamaño de la ventana para ver el ajuste dinámico del tamaño de los
controles TreeView y ListView.

Crear un origen de datos


El origen de datos para la aplicación FolderExplorer es una clase denominada Folder.
Esta clase proporciona un modelo simple de sistema de archivos. Cada instancia
deFolder tiene una colección SubFolders y una colección Files.
Para crear un origen de datos
1. Agregue una nueva clase denominada Folder al proyecto FolderExplorer. Para
obtener más información, vea How to: Add New Project Items.
2. Reemplace el contenido del archivo de código fuente Folder con el código
siguiente.

C#

using System;
using System.IO;
using System.Linq;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;

namespace FolderExplorer
{
public class Folder
{
private DirectoryInfo _folder;
private ObservableCollection<Folder> _subFolders;
private ObservableCollection<FileInfo> _files;

public Folder()
{
this.FullPath = @"c:\";
}

public string Name


{
get
{
return this._folder.Name;
}
}

public string FullPath


{
get
{
return this._folder.FullName;
}

set
{
if (Directory.Exists(value))
{
this._folder = new DirectoryInfo(value);
}
else
{
throw new ArgumentException("must exist",
"fullPath");
}
}
}

public ObservableCollection<FileInfo> Files


{
get
{
if (this._files == null)
{
this._files = new
ObservableCollection<FileInfo>();

FileInfo[] fi = this._folder.GetFiles();

for (int i = 0; i < fi.Length; i++)


{
this._files.Add(fi[i]);
}
}

return this._files;
}
}

public ObservableCollection<Folder> SubFolders


{
get
{
if (this._subFolders == null)
{
this._subFolders = new
ObservableCollection<Folder>();

DirectoryInfo[] di =
this._folder.GetDirectories();

for (int i = 0; i < di.Length; i++)


{
Folder newFolder = new Folder();
newFolder.FullPath = di[i].FullName;
this._subFolders.Add(newFolder);
}
}

return this._subFolders;
}
}
}
}

Conectarse a un origen de datos


Los controles de WPF se conectan a los orígenes de datos mediante enlaces de datos.
En el procedimiento siguiente se muestra cómo declarar un objetoObjectDataProvider
y enlazarse a él.
Para conectarse a un origen de datos
1. Abra MainWindow.xaml en WPF Designer.
2. En la vista XAML, inserte el XAML siguiente en la etiqueta <Window>, con las
demás asignaciones de xmlns. Para obtener más información, vea Cómo:
Importar un espacio de nombres a XAML.
3. xmlns:my="clr-namespace:FolderExplorer"
4. Inserte el XAML siguiente después de la etiqueta de apertura <Window> y
antes de la etiqueta de apertura <Grid>.

XAML
<Window.Resources>

<ObjectDataProvider x:Key="RootFolderDataProvider" >


<ObjectDataProvider.ObjectInstance>
<my:Folder FullPath="c:\"/>
</ObjectDataProvider.ObjectInstance>
</ObjectDataProvider>

<HierarchicalDataTemplate
DataType = "{x:Type my:Folder}"
ItemsSource = "{Binding Path=SubFolders}">
<TextBlock Text="{Binding Path=Name}" />
</HierarchicalDataTemplate>

</Window.Resources>

5. Reemplace la etiqueta <TreeView> con el XAML siguiente.

XAML

<TreeView Grid.ColumnSpan="1" Grid.RowSpan="2"


Margin="0,0,0,0" Name="treeView1" >
<TreeViewItem ItemsSource="{Binding
Path=SubFolders, Source={StaticResource
RootFolderDataProvider}}" Header="Folders" />
</TreeView>

Enlazar las propiedades de los controles


Puede enlazar las propiedades de un control a otro, lo que permite actualizarlas de
manera automática.
Para enlazar las propiedades de los controles
1. En la vista XAML, reemplace las dos etiquetas <ListView> con el XAML
siguiente.
XAML

<ListView Name="listView1"
ItemsSource="{Binding Path=SelectedItem.SubFolders,
ElementName=treeView1, Mode=OneWay}"
Grid.Column="1"
Grid.RowSpan="1" />

<ListView Name="listView2"
ItemsSource="{Binding Path=SelectedItem.Files,
ElementName=treeView1, Mode=OneWay}"
Grid.Column="1"
Grid.Row="1" />

2. Compile y ejecute la solución.


3. Expanda el elemento Carpetas para ver las carpetas de la unidad C:.
4. Experimente haciendo clic en las subcarpetas y observando el contenido de
los dos controles ListView.
Las subcarpetas se muestran en el control ListView superior y los archivos se
muestran en el control ListView inferior.

Pasos siguientes
 Actualmente, la aplicación FolderExplorer se muestra con los estilos
predeterminados. Puede aplicar sus propios estilos para cambiar el aspecto de
la aplicación y su comportamiento.
 Visual Studio también proporciona numerosas herramientas para depurar la
aplicación de WPF. Para obtener más información, vea Tutorial: Depurar
controles personalizados de WPF en tiempo de diseño.
Tutorial: Crear un diseño
dinámico
[Esta documentación se proporciona solo para fines preliminares y está sujeta a
cambios en versiones posteriores. Se incluye temas en blanco como marcadores].
En posición dinámica, los elementos secundarios se organizan especificando cómo
deberían estar organizados y cómo deberían ajustarse en relación con sus elementos
primarios. También puede establecer ventanas y controles para que se expandan
automáticamente cuando su contenido se expanda. Para obtener más información,
veaDiseño con posición absoluta y dinámica.
WPF Designer para Visual Studio proporciona muchos controles Panel que admiten la
posición dinámica. Los controles de panel se pueden combinar agregando un control
de panel como elemento secundario de otro control. Puede usar los siguientes
controles de panel para colocar los elementos en sus aplicaciones dinámicamente:
 Grid
 DockPanel
 WrapPanel
 StackPanel
 UniformGrid

Importante

Siempre que sea posible, es preferible usar un diseño dinámico. Los


diseños dinámicos son los más flexibles, se adaptan a los cambios
realizados en el contenido, por ejemplo, cuando se localizan y permiten que
el usuario final pueda controlar al máximo el entorno. Para ver un ejemplo
de un diseño absoluto,
En este tutorial realizará las siguientes tareas:
 Crear una aplicación de WPF.
 Configurar el control de panel Grid predeterminado.
 Agregar controles al panel.
 Probar el diseño.
En la ilustración siguiente se muestra la apariencia que tendrá la aplicación.
Note

Los cuadros de diálogo y comandos de menú que se ven pueden diferir de


los descritos en la Ayuda, en función de los valores de configuración o de
edición activos. Para cambiar la configuración, elija Importar y exportar
configuraciones en el menú Herramientas.

Requisitos previos
Necesita los componentes siguientes para completar este tutorial:

Crear el proyecto
El primer procedimiento es crear el proyecto para la aplicación.
Para crear el proyecto
1. Cree un nuevo proyecto de aplicación de WPF en Visual Basic o en Visual C#
denominado DynamicLayout. Para obtener más información

Note

En este tutorial, no escribirá ningún código. El lenguaje que elija para el


proyecto será el lenguaje que se utilice para las páginas de código
subyacente de la aplicación.
2. MainWindow.xaml se abrirá en WPF Designer.
3. En la Vista de diseño, seleccione la ventana. Para obtener más información,
vea Cómo: Seleccionar y mover elementos en la superficie de diseño.
4. En la ventana Propiedades, defina las propiedades siguientes para Window:

Propiedad. Valor

Ancho 400

Alto 200

SizeToContent WidthAndHeight

Tip

También puede utilizar el asa de ajuste de tamaño para


cambiar el tamaño de la ventana en la Vista de diseño.
5. En el menú Archivo, haga clic en Guardar todo.

Configurar el control de panel de cuadrícula


predeterminado
De forma predeterminada, la nueva aplicación de WPF contiene un Window con un
panel Grid. En este procedimiento se agregan cuatro filas y cuatro columnas a la
cuadrícula. El ancho de cada columna se establece en *, para que el ancho disponible
esté dividido uniformemente entre las cuatro columnas. El alto de tres de las filas se
establece en Auto, para que se dimensionen para ajustar el contenido. El alto de una
de las filas se establece en *, para que use el alto disponible restante.

Para agregar un control de panel


1. En la Vista de diseño, seleccione la cuadrícula.

2. (Opcional) En la ventana Propiedades, busque la propiedad ShowGridLines y


active la casilla.
Cuando la aplicación se ejecute, las líneas de la cuadrícula aparecerán en la
ventana. Esto resulta útil para depurar, pero debe desactivar la casilla de la
propiedad ShowGridLines para el código de producción.

3. En la ventana Propiedades, busque la propiedad ColumnDefinitions y haga


clic en el botón de puntos suspensivos en la columna del valor de propiedad.
Aparecerá el cuadro de diálogo Editor de colecciones.
a. Haga clic en Agregar cuatro veces para agregar cuatro columnas.
b. Establezca la propiedad Width de la primera fila en Auto.
c. Establezca la propiedad Width de la segunda fila en *.
d. Establezca la propiedad Width de la tercera fila en Auto.
e. Establezca la propiedad Width de la cuarta fila en Auto.
f. Haga clic en Aceptar para cerrar el Editor de colecciones y volver a
WPF Designer.
Ahora hay cuatro columnas en la cuadrícula, pero sólo aparece una
columna. Las columnas cuya propiedad Width está establecida en
Auto se ocultan temporalmente porque no tienen ningún contenido.
Para el propósito de este tutorial, esto está bien. Pero para evitarlo en
el futuro, puede utilizar el ajuste del tamaño mediante asterisco
mientras trabaja, y cambiar a Auto cuando haya terminado.

4. En la ventana Propiedades, busque la propiedad RowDefinitions y haga clic


en el botón de puntos suspensivos en la columna del valor de propiedad.
Aparecerá el cuadro de diálogo Editor de colecciones.
a. Haga clic en Agregar cuatro veces para agregar cuatro filas.
b. Establezca la propiedad Height de la primera fila en Auto.
c. Establezca la propiedad Height de la segunda fila en Auto.
d. Establezca la propiedad Height de la tercera fila en *.
e. Establezca la propiedad Height de la cuarta fila en Auto.
f. Haga clic en Aceptar para cerrar el Editor de colecciones y volver a
WPF Designer.
Ahora hay cuatro filas en la cuadrícula, pero sólo aparece una fila. Las
filas cuya propiedad Height está establecida en Auto se ocultan
temporalmente porque no tienen ningún contenido. Para el propósito
de este tutorial, esto está bien. Pero para evitarlo en el futuro, puede
utilizar el ajuste del tamaño mediante asterisco mientras trabaja, y
cambiar a Auto cuando haya terminado.

5. En el menú Archivo, haga clic en Guardar todo.


Agregar controles al panel
A continuación va a agregar controles al panel y a usar las propiedades adjuntas
Column y Row de Grid para colocarlos dinámicamente.
Para agregar controles al panel
1. En el Cuadro de herramientas, en el grupo Común, arrastre un control Label
hasta Grid.
2. En la ventana Propiedades, establezca las siguientes propiedades de Label:

Propiedad. Valor

Content Nombre:

Grid.Column 0

Grid.ColumnSpan 1

Grid.Row 0

Grid.RowSpan 1

Ancho Auto

Alto 23

HorizontalAlignment Stretch

VerticalAlignment Top

Margin 20,20,10,10

3. En el Cuadro de herramientas, en el grupo Común, arrastre un control Label


hasta Grid.
4. En la ventana Propiedades, establezca las siguientes propiedades de Label:
Propiedad. Valor

Content Password:

Grid.Column 0

Grid.ColumnSpan 1

Grid.Row 1

Grid.RowSpan 1

Ancho Auto

Alto 23

HorizontalAlignment Stretch

VerticalAlignment Top

Margin 20,10,10,10
5. En el Cuadro de herramientas, en el grupo Común, arrastre un control
TextBox hasta Grid.
6. En la ventana Propiedades, establezca las siguientes propiedades de TextBox:

Propiedad. Valor

Grid.Column 1

Grid.ColumnSpan 3

Grid.Row 0

Grid.RowSpan 1
Ancho Auto

Alto Auto

HorizontalAlignment Stretch

VerticalAlignment Stretch

Margin 10,20,20,10
7. En el Cuadro de herramientas, en el grupo Común, arrastre un control
TextBox hasta Grid.
8. En la ventana Propiedades, establezca las siguientes propiedades de TextBox:

Propiedad. Valor

Grid.Column 1

Grid.ColumnSpan 3

Grid.Row 1

Grid.RowSpan 1

Ancho Auto

Alto Auto

HorizontalAlignment Stretch

VerticalAlignment Stretch

Margin 10,10,20,10
9. En el Cuadro de herramientas, en el grupo Común, arrastre un control
Button hasta Grid.
10. En la ventana Propiedades, establezca las siguientes propiedades de Button:
Propiedad. Valor

Content OK

Grid.Column 2

Grid.ColumnSpan 1

Grid.Row 3

Grid.RowSpan 1

Ancho 75

Alto 23

HorizontalAlignment Stretch

VerticalAlignment Stretch

Margin 10,10,6,20
11. En el Cuadro de herramientas, en el grupo Común, arrastre un control
Button hasta Grid.
12. En la ventana Propiedades, establezca las siguientes propiedades de Button:

Propiedad. Valor

Content Cancelar

Grid.Column 3

Grid.ColumnSpan 1

Grid.Row 3
Grid.RowSpan 1

Ancho 75

Alto 23

HorizontalAlignment Stretch

VerticalAlignment Stretch

Margin 6,10,20,20
13. En el menú Archivo, haga clic en Guardar todo.

Probar el diseño
Finalmente se ejecuta la aplicación y se comprueba que el diseño cambia
dinámicamente a medida que el usuario cambia el tamaño de la ventana y a medida
que el contenido de los controles se expande más allá del tamaño de los controles.
Para probar el diseño
1. En el menú Depurar, haga clic en Iniciar depuración.
La aplicación se inicia y aparece la ventana.
2. En el cuadro de texto Nombre, escriba de forma aleatoria para rellenar el
cuadro de texto. Al llegar al fin del cuadro de texto, el cuadro de texto y la
ventana se expandirán para ajustar el texto que está escribiendo.
3. Cierre la ventana.
4. En el menú Depurar, haga clic en Iniciar depuración.
La aplicación se inicia y aparece la ventana.
5. Cambie el tamaño de la ventana tanto vertical como horizontalmente.
Las columnas se expandirán uniformemente para usar el espacio disponible.
Los cuadros de texto se ajustan para rellenar las columnas expandidas. Tres
filas mantienen su alto y la cuarta fila se expandirá para usar el espacio
disponible.
6. Cierre la ventana.
7. En la Vista de diseño, seleccione la etiqueta Nombre.
8. En la ventana Propiedades, cambie la propiedad Content a Please enter your
full name here:.
En la Vista de diseño, la etiqueta se expande para ajustar el texto.
9. En el menú Depurar, haga clic en Iniciar depuración.
La aplicación se inicia y aparece la ventana. El control de etiqueta muestra el
texto más largo.
10. Cierre la ventana.

Resultado final
A continuación se muestra el archivo MainWindow.xaml completo:
XAML

<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="200" Width="400"
SizeToContent="WidthAndHeight">
<Grid ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Grid.Row="0" Margin="20,20,10,10"
Width="Auto" Height="23" HorizontalAlignment="Stretch"
VerticalAlignment="Top" Name="Label1">Name:</Label>
<Label Grid.Column="0" Grid.Row="1" Margin="20,10,10,10"
Width="Auto" Height="23" HorizontalAlignment="Stretch"
VerticalAlignment="Top" Name="Label2">Password:</Label>
<TextBox Grid.Column="1" Grid.Row="0" Margin="10,20,20,10"
Grid.ColumnSpan="3" Height="Auto" VerticalAlignment="Stretch"
Name="TextBox1" />
<TextBox Grid.Column="1" Grid.Row="1" Margin="10,10,20,10"
Grid.ColumnSpan="3" Name="TextBox2" />
<Button Grid.Column="2" Grid.Row="3" Margin="10,10,6,20"
Width="75" Height="23" HorizontalAlignment="Stretch"
Name="Button1">OK</Button>
<Button Grid.Column="3" Grid.Row="3" Margin="6,10,20,20"
Width="75" Height="23" Name="Button2">Cancel</Button>
</Grid>
</Window>

Pasos siguientes
Puede realizar pruebas para aprender a lograr diferentes efectos con diseños
dinámicos reemplazando el panel Grid de este tutorial por los paneles siguientes:
 DockPanel
 WrapPanel
 StackPanel
 UniformGrid
Tutorial: Crear una aplicación cuyo
tamaño pueda ser modificado
mediante WPF Designer
[Esta documentación se proporciona solo para fines preliminares y está sujeta a
cambios en versiones posteriores. Se incluye temas en blanco como marcadores].
Puede utilizar el control GridSplitter junto con el control contenedor Grid para crear
diseños de ventanas cuyo tamaño pueda ajustar el usuario en tiempo de ejecución.
Por ejemplo, en una aplicación que tiene una interfaz dividida en áreas, el usuario
puede arrastrar un divisor para agrandar una de ellas, dependiendo de la que desee
ver mejor.En este tutorial se crea el diseño para una aplicación como las de mensajería.

En este tutorial realizará las siguientes tareas:


 Crear una aplicación de WPF.
 Configurar el panel de cuadrícula predeterminado.
 Agregar un GridSplitter horizontal.
 Agregar un panel de acoplamiento y controles.
 Agregar un panel de cuadrícula y controles.
 Probar la aplicación.
En la ilustración siguiente se muestra la apariencia que tendrá la aplicación.
Note

Los cuadros de diálogo y comandos de menú que se ven pueden diferir de


los descritos en la Ayuda, en función de los valores de configuración o de
edición activos. Para cambiar la configuración, elija Importar y exportar
configuraciones en el menú Herramientas. Para obtener más información,
vea Valores de configuración de Visual Studio.

Requisitos previos
Necesita los componentes siguientes para completar este tutorial:

Crear el proyecto
El primer procedimiento es crear el proyecto para la aplicación.
Para crear el proyecto
1. Cree un nuevo proyecto de aplicación de WPF en Visual Basic o en Visual C#
denominado ResizableApplication. Para obtener más información,

Note

En este tutorial, no escribirá ningún código. El lenguaje que elija para el


proyecto será el lenguaje que se utilice para las páginas de código subyacente
de la aplicación.
2. MainWindow.xaml se abrirá en WPF Designer.
3. En el menú Archivo, haga clic en Guardar todo.

Configurar el control de panel de cuadrícula


predeterminado
De forma predeterminada, la nueva aplicación de WPF contiene un Window con un
panel Grid. Para seguir los procedimientos recomendados, este control Grid se dedica
al objeto GridSplitter. El plano de la cuadrícula es el siguiente:
Fila 1: un panel Dock para la primera parte del diseño.
Fila 2: un GridSplitter.
Fila 3: un panel Grid para el resto del diseño.
Para configurar el control de panel de cuadrícula predeterminado
1. En la vista Diseño, seleccione Grid. Para obtener más información, vea Cómo:
Seleccionar y mover elementos en la superficie de diseño.
2. En la ventana Propiedades, busque la propiedad RowDefinitions y haga clic
en el botón de puntos suspensivos en la columna de valores de propiedad.
Aparecerá el Editor de colecciones.
3. Haga clic en Agregar tres veces para agregar tres filas.
4. Establezca la propiedad Height de la segunda fila en Auto.
5. Establezca la propiedad MinHeight de la tercera fila en 70.
6. Haga clic en Aceptar para cerrar el Editor de colecciones y volver a WPF
Designer.
Ahora hay tres filas en la cuadrícula, pero sólo aparecen dos. La fila cuya
propiedad Height está establecida en Auto se oculta temporalmente porque
no tiene contenido. Para el propósito de este tutorial, esto está bien. Pero para
evitarlo en el futuro, puede utilizar el ajuste del tamaño mediante asterisco
mientras trabaja, y cambiar a Auto cuando haya terminado.
7. En el menú Archivo, haga clic en Guardar todo.

Agregar un objeto GridSplitter horizontal


A continuación, se agrega el objeto GridSplitter.
Para agregar un objeto GridSplitter horizontal
1. En la vista Diseño, seleccione Grid.
2. Desde el Cuadro de herramientas, arrastre un control GridSplitter hasta Grid.
3. En la ventana Propiedades, establezca las siguientes propiedades de
GridSplitter:

Propiedad. Valor

ResizeDirection Filas

Grid.Column 0

Grid.ColumnSpan 1

Grid.Row 1
Grid.RowSpan 1

Ancho Auto

Alto 10

HorizontalAlignment Stretch

VerticalAlignment Stretch

Margin 0
4. En el menú Archivo, haga clic en Guardar todo.

Agregar un panel de acoplamiento y controles


A continuación, se agrega un panel DockPanel y se configura el diseño de la mitad
superior de la aplicación. DockPanel contiene un control Label y un control
RichTextBox.Establezca el color de Label y de RichTextBox para resaltar el tamaño de la
mitad superior de la aplicación cuando mueva el objeto GridSplitter.

Para agregar un panel de acoplamiento y controles


1. En la vista Diseño, seleccione Grid.
2. Desde el Cuadro de herramientas, arrastre un control DockPanel hasta Grid.
3. En la ventana Propiedades, establezca las siguientes propiedades de
DockPanel:

Propiedad. Valor

Grid.Column 0

Grid.ColumnSpan 1

Grid.Row 0

Grid.RowSpan 1
LastChildFill True (activada)

Ancho Auto

Alto Auto

HorizontalAlignment Stretch

VerticalAlignment Stretch

Margin 0
4. En el Cuadro de herramientas, arrastre un control Label hasta DockPanel.
5. En la ventana Propiedades, establezca las siguientes propiedades de Label:

Propiedad. Valor

Background Blue (#FF0000FF)

Foreground White (#FFFFFFFF)

Content Display

DockPanel.Dock Top

Ancho Auto

Alto 23

HorizontalAlignment Stretch

VerticalAlignment Stretch

Margin 0
6. En la vista Diseño, seleccione DockPanel.
Tip

Dado que hay varios controles que cubren la cuadrícula, puede


utilizar la tecla TAB, la ventana Esquema del documento o la vista
XAML para seleccionar más fácilmente el DockPanel. Para obtener
más información, vea Cómo: Seleccionar y mover elementos en la
superficie de diseño.
7. Desde el Cuadro de herramientas, arrastre un control RichTextBox hasta
DockPanel.
8. En la ventana Propiedades, establezca las siguientes propiedades de
RichTextBox:

Propiedad. Valor

Background LightBlue (#FFADD8E6)

DockPanel.Dock Bottom

Ancho Auto

Alto Auto

HorizontalAlignment Stretch

VerticalAlignment Stretch

Margin 0

IsReadOnly True (activada)


9. En el menú Archivo, haga clic en Guardar todo.

Agregar un panel de cuadrícula y controles


A continuación, se agrega una Grid y se configura el diseño de la mitad inferior de la
aplicación. Grid contiene un control Button y un control RichTextBox. Establezca el
color de RichTextBox para resaltar el tamaño de la mitad inferior de la aplicación
cuando mueva el objeto GridSplitter.
Para agregar un panel de cuadrícula y controles
1. En la vista Diseño, seleccione Grid.
2. Desde el Cuadro de herramientas, arrastre un control Grid hasta Grid.
3. En la ventana Propiedades, establezca las propiedades siguientes para la
nueva Grid:

Propiedad. Valor

Grid.Column 0

Grid.ColumnSpan 1

Grid.Row 2

Grid.RowSpan 1

Ancho Auto

Alto Auto

HorizontalAlignment Stretch

VerticalAlignment Stretch

Margin 0
4. En la ventana Propiedades, busque la propiedad ColumnDefinitions y haga
clic en el botón de puntos suspensivos en la columna de valores de propiedad.
Aparecerá el Editor de colecciones.
5. Haga clic en Agregar dos veces para agregar dos columnas.
6. Establezca la propiedad Width de la segunda columna en Auto.
7. Haga clic en Aceptar para cerrar el Editor de colecciones y volver a WPF
Designer.
8. Desde el Cuadro de herramientas, arrastre un control Button hasta Grid.
9. En la ventana Propiedades, establezca las siguientes propiedades de Button:
Propiedad. Valor

Content OK

Grid.Column 1

Grid.ColumnSpan 1

Grid.Row 0

Grid.RowSpan 1

Ancho 60

Alto 60

HorizontalAlignment Stretch

VerticalAlignment Stretch

Margin 5
10. En el Cuadro de herramientas, arrastre un control RichTextBox hasta Grid.
11. En la ventana Propiedades, establezca las siguientes propiedades de
RichTextBox:

Propiedad. Valor

Background PaleGoldenrod (#FFEEE8AA)

Grid.Column 0

Grid.ColumnSpan 1

Grid.Row 0
Grid.RowSpan 1

Ancho Auto

Alto Auto

HorizontalAlignment Stretch

VerticalAlignment Stretch

Margin 0

IsReadOnly False (desactivada)


12. En el menú Archivo, haga clic en Guardar todo.

Probar la aplicación
El último procedimiento consiste en probar la aplicación.
Para probar la aplicación
1. En el menú Depurar, haga clic en Iniciar depuración.
La aplicación se iniciará y aparecerá MainWindow.
2. Cambie el tamaño de la ventana tanto vertical como horizontalmente.
Las mitades superior e inferior de la aplicación se expanden y contraen para
utilizar el espacio disponible.
3. Arrastre el divisor para cambiar el tamaño de las partes de la aplicación.
Reduzca mucho una parte de la aplicación.
4. Cambie de nuevo el tamaño de la ventana.
Las mitades superior e inferior de la aplicación se expanden y contraen
proporcionalmente de acuerdo con la ubicación del divisor.
5. Arrastre el divisor tanto como pueda hacia la parte superior de la aplicación.
La mitad superior de la aplicación desaparece y se muestra la mitad inferior.
6. Arrastre el divisor tanto como pueda hacia la parte inferior de la aplicación.
La mitad inferior de la aplicación se sigue mostrando. Esto se debe a que
estableció la propiedad MinHeight de la tercera fila en 70.
Note

70 = 60 (el alto del botón) + 5 (el margen superior del botón) + 5 (el
margen inferior del botón)
1. Cierre la ventana.

Resultado final
A continuación se muestra el archivo MainWindow.xaml completo:
XAML

<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="300" Width="300">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
<RowDefinition MinHeight="70" />
</Grid.RowDefinitions>
<DockPanel Grid.Row="0" Grid.RowSpan="1"
HorizontalAlignment="Stretch" Margin="0" Name="DockPanel1">
<Label DockPanel.Dock="Top" Height="23" Width="Auto"
Background="Blue" Foreground="White" Name="Label1">Display</Label>
<RichTextBox DockPanel.Dock="Bottom" Height="Auto"
Width="Auto" Background="LightBlue" IsReadOnly="True"
Name="RichTextBox1" />
</DockPanel>
<GridSplitter Grid.Row="1" Grid.RowSpan="1"
ResizeDirection="Rows" Width="Auto" Height="10"
HorizontalAlignment="Stretch" Margin="0" Name="GridSplitter1" />
<Grid Grid.Row="2" HorizontalAlignment="Stretch" Margin="0"
Name="Grid1">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Button Grid.Column="1" HorizontalAlignment="Stretch"
Margin="5" Width="60" Height="60" Name="Button1">OK</Button>
<RichTextBox Grid.Column="0" Grid.ColumnSpan="1"
HorizontalAlignment="Stretch" Margin="0" Background="PaleGoldenrod"
Name="RichTextBox2" />
</Grid>
</Grid>
</Window>

Pasos siguientes
La aplicación que creó en este tutorial contenía un divisor horizontal. Puede
experimentar creando la misma aplicación pero con un divisor vertical.
La aplicación creada muestra únicamente técnicas de diseño. Puede experimentar
agregando código que haga que la aplicación sea funcional. Por ejemplo, puede
agregar código al evento clic de botón para que se copie el texto del cuadro de texto
inferior en el cuadro de texto superior.
Tutorial: Crear un enlace de
datos mediante WPF Designer
[Esta documentación se proporciona solo para fines preliminares y está sujeta a
cambios en versiones posteriores. Se incluye temas en blanco como marcadores].
En este tutorial se muestra cómo usar WPF Designer para Visual Studio para crear
enlaces de datos que conectan los datos a un control.

En este tutorial realizará las siguientes tareas:


 Crear el proyecto.
 Crear una clase Student y una colección StudentList.
 Crear un control ListBox que muestra la colección StudentList a través de un
enlace de datos.
 Crear un objeto DataTemplate personalizado que usa un IValueConverter para
personalizar la apariencia de una propiedad Boolean.

Cuando haya terminado, tendrá un cuadro de lista que se enlaza a una lista de
estudiantes. Para cada uno de los elementos de dicho cuadro, se muestra un cuadrado
coloreado que indica si el estudiante está inscrito actualmente.

Note

Para enlazar a los datos de una conexión de datos, use la ventana Orígenes
de datos. Para obtener más información, vea Enlazar controles WPF a datos
en Visual Studio.

Note

Los cuadros de diálogo y comandos de menú que se ven pueden diferir de


los descritos en la Ayuda, en función de los valores de configuración o de
edición activos. Para cambiar la configuración, elija Importar y exportar
configuraciones en el menú Herramientas. Para obtener más información,
vea Valores de configuración de Visual Studio.
Requisitos previos
Necesita los componentes siguientes para completar este tutorial:
 Visual Studio 2010.

Crear el proyecto
El primer paso consiste en crear el proyecto de aplicación WPF y agregar el origen de
datos. El origen de datos es un objeto ObservableCollection<T> que contiene
instancias de una clase Student simple. El proyecto también tiene un objeto
IValueConverter y un objeto DataTemplate personalizado para aplicar estilo al control
ListBox.
Para crear el proyecto
1. Cree un nuevo proyecto de aplicación WPF en Visual Basic o en Visual C#
denominado DataBindingDemo. Para obtener más información, vea Cómo:
Crear un nuevo proyecto de aplicación de WPF.
MainWindow.xaml se abrirá en WPF Designer.
2. Agregue al proyecto una nueva clase denominada Student. Para obtener más
información, vea How to: Add New Project Items.
3. Reemplace el código generado automáticamente por el código siguiente.

C#

using System;
using System.Collections.ObjectModel;
using System.Windows;

namespace DataBindingDemo
{
// Student is a simple class that stores a name and an
// IsEnrolled value.
public class Student
{
// The default constructor is required for creation
from XAML.
public Student()
{
}
// The StudentName property is a string that holds the
first and last name.
public string StudentName { get; set; }

// The IsEnrolled property gets or sets a value


indicating whether
// the student is currently enrolled.
public bool IsEnrolled { get; set; }
}

// The StudentList collection is declared for convenience,


// because declaring generic types in XAML is inconvenient.
public class StudentList : ObservableCollection<Student>
{

}
}

4. Agregue al proyecto una nueva clase denominada BoolToBrushConverter.


5. Reemplace el código generado automáticamente por el código siguiente.

C#

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Windows.Data;
using System.Windows.Media;

namespace DataBindingDemo
{
// The BoolToBrushConverter class is a value converter
// that helps to bind a bool value to a brush property.
[ValueConversion(typeof(bool), typeof(Brush))]
public class BoolToBrushConverter : IValueConverter
{
public object Convert(
object value,
Type targetType,
object parameter,
CultureInfo culture)
{
Brush b = null;

// Only apply the conversion if value is assigned


and
// is of type bool.
if (value != null &&
value.GetType() == typeof(bool))
{
// true is painted with a green brush,
// false with a red brush.
b = (bool)value ? Brushes.Green : Brushes.Red;
}

return b;
}

// Not used.
public object ConvertBack(
object value,
Type targetType,
object parameter,
CultureInfo culture)
{
return null;
}
}
}

6. Compile el proyecto.
7. Abra MainWindow.xaml en WPF Designer.
8. Reemplace el XAML generado automáticamente por el siguiente XAML.
XAML

<Window x:Class="DataBindingDemo.MainWindow"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:DataBindingDemo"
Title="Databinding Demo" Height="300" Width="300">
<Window.Resources>

<local:StudentList x:Key="studentCollection" >


<local:Student StudentName="Syed Abbas"
IsEnrolled="false" />
<local:Student StudentName="Lori Kane"
IsEnrolled="true" />
<local:Student StudentName="Steve Masters"
IsEnrolled="false" />
<local:Student StudentName="Tai Yee" IsEnrolled="true"
/>
<local:Student StudentName="Brenda Diaz"
IsEnrolled="true" />
</local:StudentList>

<local:BoolToBrushConverter x:Key="boolToBrushConverter"
/>

<DataTemplate x:Key="listBoxTemplate">
<StackPanel Orientation="Horizontal" >
<Rectangle Fill="{Binding Path=IsEnrolled,
Converter={StaticResource boolToBrushConverter}}"
Height="10"
Width="10"
Margin="0,0,5,0" />
<TextBlock Text="{Binding Path=StudentName}" />
</StackPanel>
</DataTemplate>

</Window.Resources>
<Grid></Grid>

</Window
Asignar un enlace de datos
Use el objeto Binding para mostrar el elemento studentCollection en el control
ListBox. WPF Designer habilita el enlace de datos sin escribir código o XAML.
Para enlazar el control ListBox al origen de datos
1. Desde el Cuadro de herramientas, arrastre un control ListBox hasta Window.
2. En la ventana Propiedades, desplácese a la propiedad ItemsSource.
3. En el borde de la columna izquierda, haga clic en el marcador de propiedad
().
Aparece un menú.

Tip

También puede hacer clic con el botón secundario en la fila para


mostrar el menú.
4. Haga clic en Aplicar enlace de datos.
Aparece el generador de enlace de datos.
5. En el recuadro Origen, en el panel izquierdo, haga clic en StaticResource.
6. En el panel intermedio, haga clic en Window.Resources.
7. En el panel derecho, haga clic en studentCollection.
El control ListBox se rellena con elementos.
8. En la ventana Propiedades, desplácese a la propiedad DisplayMemberPath y
establezca su valor en StudentName.
El control ListBox muestra la propiedad StudentName para cada instancia de
Student en studentCollection.

Crear un enlace de datos con un convertidor de


valores
Cree un objeto DataTemplate para dar formato a los datos en el control ListBox. En
este proyecto, DataTemplate usa un convertidor de valores para mostrar una
propiedad Boolean como un cuadrado coloreado.
Para crear un enlace de datos con un convertidor de valores
1. En la ventana Propiedades, borre la propiedad DisplayMemberPath.
2. Desplácese hasta la propiedad ItemTemplate.
3. Haga clic en el marcador de propiedad ().
4. Haga clic en Aplicar recurso.
Aparecerá el selector de recursos.
5. En la sección Local, haga clic en listBoxTemplate.
El control ListBox muestra junto al nombre de cada uno de los estudiantes un
cuadrado rojo o verde que indica si el estudiante se ha inscrito.
Pasos siguientes
 Para establecer las propiedades de los enlaces de datos, se puede usar el
generador de enlaces de datos. Para obtener más información, vea Cómo:
Establecer propiedades de enlace de datos con WPF Designer.
Tutorial: Usar DesignInstance para
enlazar datos en el diseñador
[Esta documentación se proporciona solo para fines preliminares y está sujeta a
cambios en versiones posteriores. Se incluye temas en blanco como marcadores].
En este tutorial se muestra cómo usar WPF Designer para Visual Studio para crear
enlaces de datos en tiempo de diseño para un contexto de datos que se asigna en
tiempo de ejecución. Para crear el enlace de datos, use el generador de enlace de
datos a fin de crear un contexto de datos en tiempo de diseño especial y
establecerDesignInstance en un tipo de objeto de negocios. DesignInstance es
una propiedad en tiempo de diseño.
En este tutorial realizará las siguientes tareas:
 Crear el proyecto.
 Crear un objeto de negocios de la clase Customer.
 Enlazar los datos de un control TextBox a una instancia en tiempo de diseño
de la clase Customer en un contexto de datos.
Cuando haya terminado, tendrá un cuadro de texto que se enlaza en tiempo de
ejecución a un objeto de negocios. El enlace de datos se establece en WPF Designer.

Note

Los cuadros de diálogo y comandos de menú que se ven pueden diferir de


los descritos en la Ayuda, en función de los valores de configuración o de
edición activos. Para cambiar la configuración, elija Importar y exportar
configuraciones en el menú Herramientas. Para obtener más información,

Requisitos previos
Necesita los componentes siguientes para completar este tutorial:
 Visual Studio 2010.

Crear el proyecto
El primer paso consiste en crear un proyecto de aplicación WPF y habilitar las
propiedades en tiempo de diseño.
Para crear el proyecto
1. Cree un nuevo proyecto de aplicación WPF en Visual Basic o en Visual C#
denominado DataBindingDemo. Para obtener más información
MainWindow.xaml se abrirá en WPF Designer.
2. En la Vista de diseño, haga clic en la etiqueta de tamaño de raíz () que aparece
en la parte inferior derecha de MainWindow para establecer la opción de ajuste
de tamaño automático para el tamaño raíz.
En la vista XAML, el diseñador agrega la asignación del espacio de nombres d,
que habilita el acceso a los atributos en tiempo de diseño, como
DesignHeight yDesignInstance.

Crear el objeto de negocios


A continuación, cree el objeto de negocios. El objeto de negocios es una clase
Customer simple que tiene las propiedades FirstName y LastName.

Note

No es necesario que el tipo de objeto de negocios se pueda crear para su uso


en el enlace de datos en tiempo de diseño. Por ejemplo, puede enlazar a una
clase abstracta en tiempo de diseño.

Para crear el objeto de negocios


1. Agregue al proyecto una nueva clase denominada Customer. Para obtener
más información, vea How to: Add New Project Items.
2. Reemplace el código generado automáticamente por el código siguiente.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DataBindingDemo
{
public class Customer
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
}
Establecer el contexto de datos en tiempo de
diseño
Para crear los enlaces de datos mediante el generador de enlace de datos, debe crear
un contexto de datos en tiempo de diseño especial y establecer DesignInstance en
el tipo del objeto de negocios.
Para establecer el contexto de datos en tiempo de diseño
1. Abra MainWindow.xaml en WPF Designer.
2. En la vista XAML, agregue la siguiente asignación de espacio de nombres a la
etiqueta de apertura de MainWindow. Para obtener más información, vea
Cómo: Importar un espacio de nombres a XAML.
3. xmlns:local="clr-namespace:DataBindingDemo"
4. Reemplace la etiqueta de apertura del elemento Grid por el código XAML
siguiente.

XAML

<Grid d:DataContext="{d:DesignInstance Type=local:Customer}"


Name="_grid">

Este código XAML establece un contexto de datos en tiempo de diseño y hace


que la clase Customer esté disponible para crear enlaces de datos.
5. Compile la solución.

Crear el enlace de datos


Ahora puede crear enlaces de datos al objeto de negocios Customer mediante el
generador de enlace de datos. En el procedimiento siguiente se muestra cómo enlazar
un control TextBox a la propiedad FirstName de un objeto Customer.
Para crear el enlace de datos
1. Desde el Cuadro de herramientas, arrastre un control TextBox hasta Window.
2. En la ventana Propiedades, desplácese a la propiedad Text.
3. En el borde de la columna izquierda, haga clic en el marcador de propiedad
().
Aparece un menú.
Tip

También puede hacer clic con el botón secundario en la fila para mostrar el menú.

4. Haga clic en Aplicar enlace de datos.


Aparece el generador de enlace de datos, con el panel Ruta de acceso
abierto.

5. Haga clic en FirstName y presione Entrar.


En la vista XAML, la propiedad Text tiene un enlace de datos a la propiedad
FirstName del tipo Customer.
Establecer el contexto de datos en tiempo de
ejecución

Por último, se asigna el contexto de datos en tiempo de ejecución. El enlace de datos


creado en tiempo de diseño funciona en tiempo de ejecución sin ningún cambio en
XAML o en el código.
Para establecer el contexto de datos en tiempo de ejecución
1. En el editor de código, abra MainWindow.xaml.cs o MainWindow.xaml.vb.
2. Reemplace el constructor MainWindow generado automáticamente por el
código siguiente.

C#

public MainWindow()
{
InitializeComponent();

Customer c = new Customer();


c.FirstName = "Brenda";
c.LastName = "Diaz";

this._grid.DataContext = c;
}

3. Presione F5 para ejecutar la aplicación.


El cuadro de texto muestra el nombre del objeto Customer que se creó en
tiempo de ejecución.
Pasos siguientes
 Puede establecer un enlace a datos en tiempo de diseño de ejemplo, lo que
ayuda a construir un comportamiento de diseño correcto en tiempo de
ejecución cuando los datos reales están disponibles. Para obtener más
información, vea Tutorial: Usar datos de ejemplo en WPF Designer.
TUTORIALES DE WPF

Tutorial: Crear un botón


mediante el uso de XAML
El objetivo de este tutorial es aprender a crear un botón animado para usarlo en una
aplicación Windows Presentation Foundation (WPF). Este tutorial utiliza estilos y una
plantilla para crear un recurso de botón personalizado que permite la reutilización de
código y la separación de la lógica del botón de la declaración del botón. Este tutorial
está escrito completamente en Lenguaje XAML.

Importante

Este tutorial sirve como guía en los pasos necesarios para crear la
aplicación escribiendo, o copiando y pegando Lenguaje XAML en
Microsoft Visual Studio. Si prefiere aprender a usar una herramienta de
diseño (Microsoft Expression Blend) para crear la misma aplicación, vea
Tutorial: Crear un botón mediante Microsoft Expression Blend.
La figura siguiente muestra los botones acabados.
Crear botones básicos
Empecemos por crear un nuevo proyecto y agregar unos botones a la ventana.
Para crear un nuevo proyecto de WPF y agregar botones a la
ventana
1. Inicie Visual Studio.
2. Cree un nuevo proyecto de WPF: En el menú Archivo, señale a Nuevo y, a
continuación, haga clic en Proyecto. Busque la plantilla Aplicación para
Windows (WPF)y asigne al proyecto el nombre "AnimatedButton". Esto
creará el esqueleto para la aplicación.
3. Agregue los botones predeterminados básicos: la plantilla proporciona
todos los archivos que necesita para este tutorial. Abra el archivo
Window1.xaml haciendo doble clic en él en el Explorador de soluciones. De
forma predeterminada, hay un elemento Grid en Window1.xaml. Quite el
elemento Grid y agregue unos botones a la página Lenguaje XAML
escribiendo o copiando y pegando el siguiente código resaltado en
Window1.xaml:
4. <Window x:Class="AnimatedButton.Window1"
5.
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentatio
n"
6. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
7. Title="AnimatedButton" Height="300" Width="300"
8. Background="Black">
9.
10. <!-- Buttons arranged vertically inside a StackPanel. -->
11. <StackPanel HorizontalAlignment="Left">
12. <Button>Button 1</Button>
13. <Button>Button 2</Button>
14. <Button>Button 3</Button>
15. </StackPanel>
16.
17. </Window>
Presione F5 para ejecutar la aplicación; debería ver un conjunto de botones
parecido a la ilustración siguiente.
Ahora que ha creado los botones básicos, ha terminado de trabajar en el archivo
Window1.xaml. El resto del tutorial se centra en el archivo app.xaml, definiendo estilos
y una plantilla para los botones.

Establecer propiedades básicas


A continuación, establezcamos algunas propiedades de estos botones para controlar
su aspecto y su diseño. En lugar de establecer individualmente las propiedades de los
botones, utilizará recursos para definir las propiedades de botón de toda la aplicación.
Los recursos de aplicación son conceptualmente similares a Hojas de estilos en
cascada (CSS) externas para páginas web; sin embargo, los recursos son mucho más
eficaces que Hojas de estilos en cascada (CSS), como verá al final de este tutorial.Para
obtener más información sobre los recursos, vea Recursos XAML.
Para utilizar estilos para establecer propiedades básicas en los
botones
1. Defina un bloque Application.Resources: abra app.xaml y agregue el
marcado resaltado siguiente si aún no está allí:
2. <Application x:Class="AnimatedButton.App"
3.
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentatio
n"
4. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
5. StartupUri="Window1.xaml"
6. >
7. <Application.Resources>
8.
9. <!-- Resources for the entire application can be
10. defined here. -->
11.
12. </Application.Resources>
13. </Application>
El ámbito del recurso lo determina dónde se defina el recurso. Definir recursos
en Application.Resoureses en el archivo app.xaml permite utilizar el recurso
en cualquier parte de la aplicación. Para obtener más información sobre cómo
definir el ámbito de los recursos, vea Recursos XAML.
14. Cree un estilo y defina los valores de propiedad básicos con él: agregue el
marcado siguiente al bloque Application.Resources. Este marcado crea un
objetoStyle que se aplica a todos los botones de la aplicación, estableciendo
la propiedad Width de los botones en 90 y Margin en 10:
15. <Application.Resources>
16.
17. <Style TargetType="Button">
18. <Setter Property="Width" Value="90" />
19. <Setter Property="Margin" Value="10" />
20. </Style>
21.
22. </Application.Resources>
La propiedad TargetType especifica que el estilo se aplica a todos los objetos
de tipo Button. Cada Setter establece un valor de propiedad diferente para el
objetoStyle. Por tanto, en este punto cada botón de la aplicación tiene un
ancho de 90 y un margen de 10. Si presiona F5 para ejecutar la aplicación,
verá la siguiente ventana.

Hay mucho más que puede hacer con estilos, incluidas diversas maneras de
ajustar con precisión a qué objetos se destinan, especificar valores de
propiedad complejos e incluso utilizar estilos como entrada para otros estilos.
Para obtener más información, consulte Aplicar estilos y plantillas.
23. Establezca un valor de propiedad de estilo en un recurso: los recursos
permiten reutilizar fácilmente objetos y valores que se definen con frecuencia.
Es especialmente útil definir valores complejos utilizando recursos, para hacer
el código más modular. Agregue el marcado resaltado siguiente a app.xaml.
24. <Application.Resources>
25.
26. <LinearGradientBrush x:Key="GrayBlueGradientBrush"
27. StartPoint="0,0" EndPoint="1,1">
28. <GradientStop Color="DarkGray" Offset="0" />
29. <GradientStop Color="#CCCCFF" Offset="0.5" />
30. <GradientStop Color="DarkGray" Offset="1" />
31. </LinearGradientBrush>
32.
33. <Style TargetType="{x:Type Button}">
34. <Setter Property="Background"
35. Value="{StaticResource GrayBlueGradientBrush}" />
36. <Setter Property="Width" Value="80" />
37. <Setter Property="Margin" Value="10" />
38. </Style>
39.
40. </Application.Resources>
Directamente bajo el bloque Application.Resources, creó un recurso llamado
"GrayBlueGradientBrush". Este recurso define un degradado horizontal. Este
recurso se puede utilizar en cualquier parte de la aplicación como un valor de
propiedad, incluso dentro del establecedor de estilo del botón para la
propiedad Background.Ahora, todos los botones tienen un valor de propiedad
Background de este degradado.
Presione F5 para ejecutar la aplicación. Debe tener este aspecto:
Crear una plantilla que define la apariencia del
botón
En esta sección creará una plantilla que personaliza la apariencia (presentación) del
botón. La presentación del botón se compone de varios objetos, que incluyen
rectángulos y otros componentes para dar una apariencia única al botón.
Hasta ahora, el control de la apariencia de los botones de la aplicación se ha
confinado a cambiar propiedades del botón. ¿Qué ocurre si desea realizar cambios
más radicales en la apariencia del botón? Las plantillas permiten un control eficaz
sobre la presentación de un objeto. Dado que las plantillas se pueden utilizar dentro
de estilos, puede aplicar una plantilla a todos los objetos a los que se aplica el estilo
(en este tutorial, el botón).
Para utilizar la plantilla para definir la apariencia del botón
1. Configure la plantilla: dado que los controles como Button tienen una
propiedad Template, puede definir el valor de la propiedad de la plantilla igual
que los demás valores de propiedades que hemos establecido en un objeto
Style, utilizando un objeto Setter. Agregue el marcado resaltado siguiente al
estilo de botón.
2. <Application.Resources>
3.
4. <LinearGradientBrush x:Key="GrayBlueGradientBrush"
5. StartPoint="0,0" EndPoint="1,1">
6. <GradientStop Color="DarkGray" Offset="0" />
7. <GradientStop Color="#CCCCFF" Offset="0.5" />
8. <GradientStop Color="DarkGray" Offset="1" />
9. </LinearGradientBrush>
10.
11. <Style TargetType="{x:Type Button}">
12. <Setter Property="Background" Value="{StaticResource
GrayBlueGradientBrush}" />
13. <Setter Property="Width" Value="80" />
14. <Setter Property="Margin" Value="10" />
15. <Setter Property="Template">
16. <Setter.Value>
17. <!-- The button template is defined here. -->
18. </Setter.Value>
19. </Setter>
20. </Style>
21.
22. </Application.Resources>
23. Modifique la presentación del botón: en este punto, debe definir la plantilla.
Agregue el siguiente marcado resaltado: Este marcado especifica dos
elementosRectangle con bordes redondeados, seguidos por un control
DockPanel. El control DockPanel se utiliza para hospedar el objeto
ContentPresenter del botón. Un objeto ContentPresenter muestra el
contenido del botón. En este tutorial, el contenido es texto ("Button 1",
"Button 2", "Button 3"). Todos los componentes de la plantilla (los rectángulos
y el control DockPanel) se disponen dentro de un control Grid.
24. <Setter.Value>
25. <ControlTemplate TargetType="Button">
26. <Grid Width="{TemplateBinding Width}"
27. Height="{TemplateBinding Height}" ClipToBounds="True">
28.
29. <!-- Outer Rectangle with rounded corners. -->
30. <Rectangle x:Name="outerRectangle"
31. HorizontalAlignment="Stretch"
32. VerticalAlignment="Stretch"
33. Stroke="{TemplateBinding Background}"
34. RadiusX="20" RadiusY="20" StrokeThickness="5"
35. Fill="Transparent" />
36.
37. <!-- Inner Rectangle with rounded corners. -->
38. <Rectangle x:Name="innerRectangle"
39. HorizontalAlignment="Stretch"
40. VerticalAlignment="Stretch" Stroke="Transparent"
41. StrokeThickness="20"
42. Fill="{TemplateBinding Background}"
43. RadiusX="20" RadiusY="20" />
44.
45. <!-- Present Content (text) of the button. -->
46. <DockPanel Name="myContentPresenterDockPanel">
47. <ContentPresenter x:Name="myContentPresenter"
Margin="20"
48. Content="{TemplateBinding Content}"
49. TextBlock.Foreground="Black" />
50. </DockPanel>
51. </Grid>
52. </ControlTemplate>
53. </Setter.Value>
Presione F5 para ejecutar la aplicación. Debe tener este aspecto:

54. Agregue un efecto de vidrio a la plantilla: a continuación agregará el vidrio.


Primero cree algunos recursos que creen un efecto de degradado de vidrio.
Agregue estos recursos de degradado en cualquier punto del bloque
Application.Resources:
55. <Application.Resources>
56. <GradientStopCollection x:Key="MyGlassGradientStopsResource">
57. <GradientStop Color="WhiteSmoke" Offset="0.2" />
58. <GradientStop Color="Transparent" Offset="0.4" />
59. <GradientStop Color="WhiteSmoke" Offset="0.5" />
60. <GradientStop Color="Transparent" Offset="0.75" />
61. <GradientStop Color="WhiteSmoke" Offset="0.9" />
62. <GradientStop Color="Transparent" Offset="1" />
63. </GradientStopCollection>
64.
65. <LinearGradientBrush x:Key="MyGlassBrushResource"
66. StartPoint="0,0" EndPoint="1,1" Opacity="0.75"
67. GradientStops="{StaticResource
MyGlassGradientStopsResource}" />
68. <!-- Styles and other resources below here. -->
Estos recursos se utilizan como propiedad Fill para un rectángulo que
insertamos en el control Grid de la plantilla de botón. Agregue el siguiente
marcado resaltado a la plantilla.
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}"
ClipToBounds="True">

<!-- Outer Rectangle with rounded corners. -->


<Rectangle x:Name="outerRectangle"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" Stroke="{TemplateBinding
Background}"
RadiusX="20" RadiusY="20" StrokeThickness="5"
Fill="Transparent" />

<!-- Inner Rectangle with rounded corners. -->


<Rectangle x:Name="innerRectangle"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" Stroke="Transparent"
StrokeThickness="20"
Fill="{TemplateBinding Background}" RadiusX="20"
RadiusY="20" />

<!-- Glass Rectangle -->


<Rectangle x:Name="glassCube" HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
StrokeThickness="2" RadiusX="10" RadiusY="10" Opacity="0"
Fill="{StaticResource MyGlassBrushResource}"
RenderTransformOrigin="0.5,0.5">
<Rectangle.Stroke>
<LinearGradientBrush StartPoint="0.5,0"
EndPoint="0.5,1">
<LinearGradientBrush.GradientStops>
<GradientStop Offset="0.0" Color="LightBlue" />
<GradientStop Offset="1.0" Color="Gray" />
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Rectangle.Stroke>
<!-- These transforms have no effect as they are declared
here.
The reason the transforms are included is to be
targets
for animation (see later). -->
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform />
<RotateTransform />
</TransformGroup>
</Rectangle.RenderTransform>

<!-- A BevelBitmapEffect is applied to give the button a


"Beveled" look. -->
<Rectangle.BitmapEffect>
<BevelBitmapEffect />
</Rectangle.BitmapEffect>
</Rectangle>

<!-- Present Text of the button. -->


<DockPanel Name="myContentPresenterDockPanel">
<ContentPresenter x:Name="myContentPresenter" Margin="20"
Content="{TemplateBinding Content}"
TextBlock.Foreground="Black" />
</DockPanel>
</Grid>
</ControlTemplate>
</Setter.Value>
Observe que la propiedad Opacity del rectángulo con la propiedad x:Name
de "glassCube" es 0, por lo que al ejecutar el ejemplo no verá el rectángulo de
vidrio superpuesto. Esto se debe a que agregaremos después a la plantilla los
desencadenadores para cuando el usuario interactúe con el botón. Sin
embargo, puede ver la apariencia que tiene ahora el botón cambiando el valor
Opacity a 1 y ejecutando la aplicación. Vea la ilustración siguiente. Antes de
continuar con el paso siguiente, vuelva a establecer Opacity en 0.
Crear la interactividad del botón
En esta sección, creará desencadenadores de propiedad y desencadenadores de
evento para cambiar valores de propiedad y ejecutar animaciones en respuesta a
acciones del usuario tales como mover el puntero del mouse sobre el botón y hacer
clic.
Una manera fácil de agregar interactividad (entrada de mouse, salida de mouse, clic,
etc.) es definir los desencadenadores dentro de la plantilla o del estilo. Para crear un
objeto Trigger, defina una propiedad "condición" tal como: el valor de propiedad
IsMouseOver del botón es igual a true. A continuación, defina establecedores
(acciones) que tengan lugar cuando la condición de activación sea verdadera.
Para crear la interactividad del botón
1. Agregue desencadenadores de plantilla: agregue el marcado resaltado a la
plantilla.
2. <Setter.Value>
3. <ControlTemplate TargetType="{x:Type Button}">
4. <Grid Width="{TemplateBinding Width}"
5. Height="{TemplateBinding Height}" ClipToBounds="True">
6.
7. <!-- Outer Rectangle with rounded corners. -->
8. <Rectangle x:Name="outerRectangle"
HorizontalAlignment="Stretch"
9. VerticalAlignment="Stretch" Stroke="{TemplateBinding
Background}"
10. RadiusX="20" RadiusY="20" StrokeThickness="5"
Fill="Transparent" />
11.
12. <!-- Inner Rectangle with rounded corners. -->
13. <Rectangle x:Name="innerRectangle"
HorizontalAlignment="Stretch"
14. VerticalAlignment="Stretch" Stroke="Transparent"
15. StrokeThickness="20"
16. Fill="{TemplateBinding Background}" RadiusX="20"
RadiusY="20"
17. />
18.
19. <!-- Glass Rectangle -->
20. <Rectangle x:Name="glassCube"
HorizontalAlignment="Stretch"
21. VerticalAlignment="Stretch"
22. StrokeThickness="2" RadiusX="10" RadiusY="10"
Opacity="0"
23. Fill="{StaticResource MyGlassBrushResource}"
24. RenderTransformOrigin="0.5,0.5">
25. <Rectangle.Stroke>
26. <LinearGradientBrush StartPoint="0.5,0"
EndPoint="0.5,1">
27. <LinearGradientBrush.GradientStops>
28. <GradientStop Offset="0.0" Color="LightBlue" />
29. <GradientStop Offset="1.0" Color="Gray" />
30. </LinearGradientBrush.GradientStops>
31. </LinearGradientBrush>
32. </Rectangle.Stroke>
33.
34. <!-- These transforms have no effect as they
35. are declared here.
36. The reason the transforms are included is to be
targets
37. for animation (see later). -->
38. <Rectangle.RenderTransform>
39. <TransformGroup>
40. <ScaleTransform />
41. <RotateTransform />
42. </TransformGroup>
43. </Rectangle.RenderTransform>
44.
45. <!-- A BevelBitmapEffect is applied to give the
button a
46. "Beveled" look. -->
47. <Rectangle.BitmapEffect>
48. <BevelBitmapEffect />
49. </Rectangle.BitmapEffect>
50. </Rectangle>
51.
52. <!-- Present Text of the button. -->
53. <DockPanel Name="myContentPresenterDockPanel">
54. <ContentPresenter x:Name="myContentPresenter"
Margin="20"
55. Content="{TemplateBinding Content}"
TextBlock.Foreground="Black" />
56. </DockPanel>
57. </Grid>
58.
59. <ControlTemplate.Triggers>
60. <!-- Set action triggers for the buttons and define
61. what the button does in response to those triggers.
-->
62. </ControlTemplate.Triggers>
63. </ControlTemplate>
64. </Setter.Value>
65. Agregue desencadenadores de propiedad: agregue el marcado resaltado al
bloque ControlTemplate.Triggers:
66. <ControlTemplate.Triggers>
67.
68. <!-- Set properties when mouse pointer is over the button. --
>
69. <Trigger Property="IsMouseOver" Value="True">
70.
71. <!-- Below are three property settings that occur when the
72. condition is met (user mouses over button). -->
73. <!-- Change the color of the outer rectangle when user
74. mouses over it. -->
75. <Setter Property ="Rectangle.Stroke"
TargetName="outerRectangle"
76. Value="{DynamicResource {x:Static
SystemColors.HighlightBrushKey}}" />
77.
78. <!-- Sets the glass opacity to 1, therefore, the
79. glass "appears" when user mouses over it. -->
80. <Setter Property="Rectangle.Opacity" Value="1"
TargetName="glassCube" />
81.
82. <!-- Makes the text slightly blurry as though you
83. were looking at it through blurry glass. -->
84. <Setter Property="ContentPresenter.BitmapEffect"
85. TargetName="myContentPresenter">
86. <Setter.Value>
87. <BlurBitmapEffect Radius="1" />
88. </Setter.Value>
89. </Setter>
90. </Trigger>
91.
92. <ControlTemplate.Triggers/>
Presione F5 para ejecutar la aplicación y ver el efecto al pasar el puntero del
mouse sobre los botones.
93. Agregue un desencadenador de foco: a continuación, agregaremos algunos
establecedores similares para administrar el caso en el que el botón tenga el
foco (por ejemplo, después de que el usuario haga clic en él).
94. <ControlTemplate.Triggers>
95.
96. <!-- Set properties when mouse pointer is over the button. --
>
97. <Trigger Property="IsMouseOver" Value="True">
98.
99. <!-- Below are three property settings that occur when the
100. condition is met (user mouses over button). -->
101. <!-- Change the color of the outer rectangle when user
mouses over it. -->
102. <Setter Property ="Rectangle.Stroke"
TargetName="outerRectangle"
103. Value="{DynamicResource {x:Static
SystemColors.HighlightBrushKey}}" />
104.
105. <!-- Sets the glass opacity to 1, therefore, the
glass "appears" when user mouses over it. -->
106. <Setter Property="Rectangle.Opacity" Value="1"
TargetName="glassCube" />
107.
108. <!-- Makes the text slightly blurry as though you were
looking at it through blurry glass. -->
109. <Setter Property="ContentPresenter.BitmapEffect"
TargetName="myContentPresenter">
110. <Setter.Value>
111. <BlurBitmapEffect Radius="1" />
112. </Setter.Value>
113. </Setter>
114. </Trigger>
115. <!-- Set properties when button has focus. -->
116. <Trigger Property="IsFocused" Value="true">
117. <Setter Property="Rectangle.Opacity" Value="1"
TargetName="glassCube" />
118. <Setter Property="Rectangle.Stroke"
TargetName="outerRectangle"
119. Value="{DynamicResource {x:Static
SystemColors.HighlightBrushKey}}" />
120. <Setter Property="Rectangle.Opacity" Value="1"
TargetName="glassCube" />
121. </Trigger>
122.
123. </ControlTemplate.Triggers>
Presione F5 para ejecutar la aplicación y haga clic en uno de los botones.
Observa que el botón permanece resaltado después de hacer clic en él,
porque todavía tiene el foco. Si hace clic en otro botón, el nuevo botón
obtendrá el foco mientras el último lo pierde.
124. Agregue animaciones para MouseEnter y MouseLeave : a
continuación, agregamos algunas animaciones a los desencadenadores.
Agregue el marcado siguiente en cualquier punto del bloque
ControlTemplate.Triggers.
125. <!-- Animations that start when mouse enters and leaves
button. -->
126. <EventTrigger RoutedEvent="Mouse.MouseEnter">
127. <EventTrigger.Actions>
128. <BeginStoryboard Name="mouseEnterBeginStoryboard">
129. <Storyboard>
130.
131. <!-- This animation makes the glass rectangle shrink in
the X direction. -->
132. <DoubleAnimation Storyboard.TargetName="glassCube"
133. Storyboard.TargetProperty=
134.
"(Rectangle.RenderTransform).(TransformGroup.Children)[0].(Scal
eTransform.ScaleX)"
135. By="-0.1" Duration="0:0:0.5" />
136.
137. <!-- This animation makes the glass rectangle shrink
in the Y direction. -->
138. <DoubleAnimation
139. Storyboard.TargetName="glassCube"
140. Storyboard.TargetProperty=
141.
"(Rectangle.RenderTransform).(TransformGroup.Children)[0].(Scal
eTransform.ScaleY)"
142. By="-0.1" Duration="0:0:0.5" />
143. </Storyboard>
144. </BeginStoryboard>
145. </EventTrigger.Actions>
146. </EventTrigger>
147. <EventTrigger RoutedEvent="Mouse.MouseLeave">
148. <EventTrigger.Actions>
149.
150. <!-- Stopping the storyboard sets all animated properties
back to default. -->
151. <StopStoryboard
BeginStoryboardName="mouseEnterBeginStoryboard" />
152. </EventTrigger.Actions>
153. </EventTrigger>
El rectángulo de vidrio se reduce cuando el puntero del mouse pasa sobre el
botón y vuelve al tamaño normal cuando el puntero sale.
Hay dos animaciones que se desencadenan cuando el puntero pasa sobre el
botón (cuando se provoca el evento MouseEnter). Estas animaciones reducen
el rectángulo de vidrio a lo largo de los ejes X e Y. Observe las propiedades de
los elementos DoubleAnimation, Duration y By. La propiedad Duration
especifica que la animación se produce durante medio segundo, y By
especifica que el vidrio se reduce un 10%.
El segundo desencadenador de eventos (MouseLeave) detiene simplemente el
primero. Al detener un objeto Storyboard, todas las propiedades animadas
vuelven a sus valores predeterminados. Por consiguiente, cuando el usuario
saca el puntero del botón, el botón vuelve a ser como era antes de que el
puntero del mouse pasara sobre el botón. Para obtener más información
acerca de las animaciones, vea Información general sobre animaciones.
154. Agregue una animación para cuando se haga clic en el botón: el
paso final es agregar un desencadenador para cuando el usuario haga clic en
el botón. Agregue el marcado siguiente en cualquier punto del bloque
ControlTemplate.Triggers.
155. <!-- Animation fires when button is clicked, causing glass to
spin. -->
156. <EventTrigger RoutedEvent="Button.Click">
157. <EventTrigger.Actions>
158. <BeginStoryboard>
159. <Storyboard>
160. <DoubleAnimation Storyboard.TargetName="glassCube"
161. Storyboard.TargetProperty=
162.
"(Rectangle.RenderTransform).(TransformGroup.Children)[1].(Rota
teTransform.Angle)"
163. By="360" Duration="0:0:0.5" />
164. </Storyboard>
165. </BeginStoryboard>
166. </EventTrigger.Actions>
167. </EventTrigger>
Presione F5 para ejecutar la aplicación y haga clic en uno de los botones. Al
hacer clic en un botón, el rectángulo de vidrio gira sobre sí mismo.

Resumen
En este tutorial, ha realizado los siguientes ejercicios:
 Ha destinado un objeto Style a un tipo de objeto (Button).
 Ha controlado propiedades básicas de los botones en toda la aplicación
utilizando el objeto Style.
 Ha creado recursos tales como degradados para utilizarlos para valores de
propiedades de los establecedores de Style.
 Ha personalizado la apariencia de botones de toda la aplicación aplicando una
plantilla a los botones.
 Ha personalizado el comportamiento de los botones en respuesta a acciones
del usuario (tales como MouseEnter, MouseLeave y Click) incluyendo efectos
de animación.
Tutorial: Crear un botón mediante
Microsoft Expression Blend
Este tutorial le guía a lo largo del proceso de creación de un botón personalizado de
WPF mediante Microsoft Expression Blend.

Importante

Microsoft Expression Blend funciona generando Lenguaje XAML que luego se compila
para crear el programa ejecutable. Si prefiere trabajar directamente con Lenguaje XAML,
hay otro tutorial que crea la misma aplicación que este utilizando Lenguaje XAML con
Visual Studio en lugar de Blend. Para obtener más información, consulteTutorial: Crear un
botón mediante el uso de XAML.

En la ilustración siguiente se muestra el botón personalizado que creará.

Convertir una forma en un Botón


En la primera parte de este tutorial, creará el aspecto personalizado del botón
personalizado. Para ello, lo primero que hará será convertir un rectángulo en un botón.
A continuación, agregará formas adicionales a la plantilla del botón para crear un
botón con un aspecto más complejo. ¿Por qué no es mejor comenzar con un botón
normal y personalizarlo? Porque un botón incluye funcionalidad integrada que no
necesita; en el caso de los botones personalizados, es más fácil comenzar por un
rectángulo.
Para crear un nuevo proyecto en Expression Blend
1. Inicie Expression Blend. (Haga clic en Inicio, seleccione Todos los programas,
Microsoft Expression y, a continuación, haga clic en Microsoft Expression
Blend.)
2. Maximice la aplicación si es necesario.
3. En el menú Archivo, haga clic en Nuevo proyecto.
4. Seleccione Aplicación estándar (.exe).
5. Asigne al proyecto el nombre BotónPersonalizado y presione Aceptar.
En este momento dispone de un proyecto de WPF en blanco. Puede presionar F5 para
ejecutar la aplicación. Como cabría esperar, la aplicación sólo contiene una ventana en
blanco. El siguiente paso consiste en crear un rectángulo redondeado y convertirlo en
un botón.
Para convertir un rectángulo en un botón
1. Establezca la propiedad Fondo de la ventana en el color negro: seleccione
la ventana, haga clic en la ficha Propiedades y establezca la propiedad
Background enBlack.
2. Dibuje un rectángulo con el tamaño aproximado de un botón en la
ventana: seleccione la herramienta Rectángulo en el panel de herramientas de
la izquierda y arrastre el rectángulo a la ventana.

3. Redondee las esquinas del rectángulo: arrastre los puntos de control del
rectángulo o establezca directamente las propiedades RadiusX y RadiusY.
Establezca los valores de RadiusX y RadiusY en 20.
4. Convierta el rectángulo en un botón: seleccione el rectángulo. En el menú
Herramientas, haga clic en Crear botón.
5. Especifique el ámbito del estilo o la plantilla: aparece un cuadro de diálogo
como el siguiente.

Para Nombre de recurso (clave), seleccione Aplicar a todo. Esto hará que el
estilo y la plantilla del botón resultantes se apliquen a todos los objetos que
sean botones. Para Definir en, seleccione Aplicación. Esto hará que el ámbito
del estilo y de la plantilla del botón resultantes sea toda la aplicación. Al
establecer los valores de estos dos cuadros, el estilo y la plantilla del botón se
aplicarán a todos los botones de la aplicación, y cualquier botón que cree en
la aplicación usará esta plantilla de forma predeterminada.

Editar la plantilla del botón


Ahora, tiene un rectángulo convertido en un botón. En esta sección, modificará la
plantilla del botón y personalizará aún más su apariencia.
Para editar la plantilla del botón con objeto de cambiar la
apariencia del botón
1. Pase a la vista de edición de plantillas: para personalizar aún más a
apariencia del botón, es necesario editar la plantilla del botón. Esta plantilla se
creó al convertir el rectángulo en un botón. Para editar la plantilla del botón,
haga clic con el botón secundario en el botón, seleccione Editar partes del
control (plantilla)y, a continuación, seleccione Editar plantilla.
En el editor de plantillas, observe que el botón ahora está separado en una
forma Rectangle y en un control ContentPresenter. ContentPresenter se utiliza
para presentar el contenido del botón (por ejemplo, la cadena "Botón"). Tanto
el rectángulo como el control ContentPresenter se sitúan dentro de un control
Grid.
2. Cambie los nombres de los componentes de la plantilla: haga clic con el
botón secundario en el rectángulo en el inventario de plantillas, cambie el
nombre de la forma Rectangle de "[Rectangle]" a "RectánguloExterior" y
cambie "[ContentPresenter]" por "MiContentPresenter".

3. Modifique el rectángulo para que esté vacío (como un anillo): seleccione


RectánguloExterior y establezca Fill en "Transparent" y StrokeThickness en 5.
A continuación, establezca Stroke en el color que tenga que tener la plantilla.
Para ello, haga clic en el cuadro blanco de pequeño tamaño situado junto a
Stroke, seleccione Expresión personalizada y escriba "{Fondo de
TemplateBinding}" en el cuadro de diálogo.
4. Cree un rectángulo interior: ahora, cree otro rectángulo (denomínelo
"RectánguloInterior") y colóquelo simétricamente dentro del
RectánguloExterior. Para este tipo de trabajo, es posible que le convenga
hacer zoom a fin de ampliar el tamaño del botón en el área de edición.

Nota

Es posible que su rectángulo presente un aspecto distinto al de la


ilustración (por ejemplo, podría tener las esquinas redondeadas).
5.
6. Mueva ContentPresenter a la parte superior: llegado a este punto, es
posible que el texto "Botón" ya no esté visible. Si es así, se debe a que
RectánguloInteriorestá encima de MiContentPresenter. Para evitarlo,
arrastre MiContentPresenter debajo de RectánguloInterior. Cambie de
posición los rectángulos yMiContentPresenter para que presenten un
aspecto similar al de la ilustración.

Nota

También puede colocar MiContentPresenter en la parte superior haciendo


clic con el botón secundario en él y presionando Traer adelante.
7.
8. Cambie el aspecto de RectánguloInterior: establezca los valores de las
propiedades RadiusX, StrokeThickness y RadiusY en 20. Además, establezca Fill
en el fondo de la plantilla utilizando la expresión personalizada "{Fondo de
TemplateBinding}" y establezca Stroke en "transparent". Observe que la
configuración para Fill yStroke de RectánguloInterior es la opuesta a la de
RectánguloExterior.
9. Agregue una capa de cristal a la parte superior: la última etapa del proceso
de personalización del aspecto del botón consiste en agregar una capa de
cristal a la parte superior. Esta capa de cristal consta de un tercer rectángulo.
Dado que el cristal cubrirá todo el botón, el rectángulo de cristal es similar en
dimensiones alRectánguloExterior. Por ello, para crear el rectángulo basta
con realizar una copia del RectánguloExterior. Resalte el RectánguloExterior
y use CTRL+C y CTRL+V para realizar una copia. Asigne a este nuevo
rectángulo el nombre "CuboCristal".
10. Cambie de posición el CuboCristal si es necesario: si el CuboCristal no está
situado de forma que cubra todo el botón, arrástrelo a la posición correcta.
11. Déle al CuboCristal una forma ligeramente distinta de la que tiene
RectánguloExterior: cambie las propiedades de CuboCristal. En primer lugar,
cambie el valor de las propiedades RadiusX y RadiusY a 10 y el valor de la
propiedad StrokeThickness a 2.
12. Haga que CuboCristal se parezca al cristal: configure Fill de forma que
presente un aspecto vítreo; para ello, utilice un degradado lineal con una
opacidad del 75% y que alterne los colores blanco y transparente en 6
intervalos espaciados de forma más o menos uniforme. Configure los puntos
de degradado tal y como se indica a continuación:
o Punto de degradado 1: blanco con valor alfa del 75%
o Punto de degradado 2: transparente
o Punto de degradado 3: blanco con valor alfa del 75%
o Punto de degradado 4: transparente
o Punto de degradado 5: blanco con valor alfa del 75%
o Punto de degradado 6: transparente
De esta forma, creará un aspecto de cristal "ondulado".
13. Oculte la capa de cristal: ahora que puede ver el aspecto de la capa de
cristal, vaya al panel Apariencia del panel Propiedades y establezca la
opacidad en 0% para ocultarla. En las secciones siguientes, utilizaremos
desencadenadores de propiedad y eventos para mostrar y manipular la capa
de cristal.
Personalizar el comportamiento del botón
Una vez llegado a este punto, ha personalizado la presentación del botón editando su
plantilla, pero el botón no reacciona a las acciones del usuario del mismo modo que
los botones normales (por ejemplo, cambiando su aspecto al pasar el puntero por
encima, recibiendo el foco o haciendo clic). Los dos procedimientos siguientes
muestran cómo hacer que el botón personalizado adopte comportamientos de este
tipo. Comenzaremos con desencadenadores de propiedad simples y, a continuación,
agregaremos desencadenadores de eventos y animaciones.
Para establecer desencadenadores de propiedad
1. Cree un nuevo desencadenador de propiedad: con CuboCristal
seleccionado, haga clic en + Propiedad en el panel Desencadenadores
(consulte la ilustración que sigue al paso siguiente). De esta forma, se creará
un desencadenador de propiedad con un desencadenador de propiedad
predeterminado.
2. Haga que el desencadenador utilice la propiedad IsMouseOver: cambie la
propiedad a IsMouseOver. De esta forma, el desencadenador de la propiedad
se activará cuando la propiedad IsMouseOver sea true (cuando el usuario
coloque el puntero sobre el botón).
3. IsMouseOver activa una opacidad del 100% para CuboCristal: observe el
estado Grabación de desencadenador activada (consulte la ilustración
anterior). Esto significa que cualquier cambio que realice en los valores de
propiedad de CuboCristal mientras la grabación esté activada se convertirá
en una acción que tendrá lugar cuando IsMouseOver sea true. Durante la
grabación, cambie el valor de la propiedad Opacity de CuboCristal a 100%.
Acaba de crear su primer desencadenador de propiedad. Observe que el panel
Desencadenadores del editor ha grabado el cambio de Opacity al 100%.

Presione F5 para ejecutar la aplicación y pase el puntero por encima del


botón. Debería ver cómo aparece la capa de cristal cuando el puntero está
sobre el botón y cómo desaparece al quitarlo de encima.
4. IsMouseOver desencadena un cambio de valor del trazo: procedamos a
asociar otras acciones al desencadenador IsMouseOver. Mientras la grabación
continúa, cambie la selección de CuboCristal a RectánguloExterior. A
continuación, establezca la propiedad Stroke de RectánguloExterior en la
expresión personalizada "{DynamicResource {x:Static
SystemColors.HighlightBrushKey}}". De esta forma, el valor de la propiedad
Stroke se establece en el color de resaltado típico que se utiliza en los
botones. Presione F5 para ver lo que ocurre al pasar el puntero sobre el botón.
5. IsMouseOver activa el texto borroso: asociemos ahora otra acción al
desencadenador de la propiedad IsMouseOver. Haga que el contenido del
botón se vea un poco borroso cuando el cristal aparezca sobre él. Para ello,
podemos aplicar un efecto BitmapEffect de desenfoque al control
ContentPresenter(MiContentPresenter).
Nota

Para devolver al panel Propiedades el estado que tenía antes de iniciar la


búsqueda de BitmapEffect, borre el texto del cuadro Buscar.
Llegados a este punto, hemos utilizado un desencadenador de propiedad con
varias acciones asociadas para crear un comportamiento de resaltado cuando
el puntero entra y sale del área del botón. Otro comportamiento típico de un
botón es permanecer resaltado cuando tiene el foco (como ocurre después de
hacer clic en él). Podemos agregar dicho comportamiento agregando otro
desencadenador de propiedad para la propiedad IsFocused.
6. Cree un desencadenador de propiedad para IsFocused: utilizando el mismo
procedimiento que para IsMouseOver (consulte el primer paso de esta
sección), cree otro desencadenador de propiedad para la propiedad
IsFocused. Desde el estado Grabación de desencadenador activada,
agregue las acciones siguientes al desencadenador:
o Para CuboCristal, Opacity se establece en el 100%.
o Para RectánguloExterior, Stroke se establece en el valor de expresión
personalizada "{DynamicResource {x:Static
SystemColors.HighlightBrushKey}}".
Como último paso de este tutorial, agregaremos animaciones al botón. Las
animaciones se desencadenarán a través de eventos, en concreto los eventos
MouseEnter yClick.
Para utilizar desencadenadores de eventos y animaciones a fin de
aportar interactividad
1. Cree un desencadenador de eventos MouseEnter: agregue un nuevo
desencadenador de eventos y seleccione MouseEnter como el evento que se
utilizará en el desencadenador.
2. Cree una escala de tiempo de animación: a continuación, asocie una escala
de tiempo de animación al evento MouseEnter.

Después de presionar Aceptar para crear una nueva escala de tiempo,


aparecerá un panel Escala de tiempo y se mostrará el mensaje "Grabación de
escala de tiempo activada" en el panel de diseño. Esto significa que se pueden
comenzar a grabar cambios de propiedades en la escala de tiempo (animar
cambios de propiedades).

Nota

Es posible que necesite cambiar el tamaño de la ventana o de los paneles


para ver la presentación.
3. Cree un fotograma clave: para crear una animación, seleccione el objeto que
desea animar, cree dos o más fotogramas clave en la escala de tiempo y
establezca los valores de propiedad entre los que desea que interpole la
animación para dichos fotogramas clave. Utilice la ilustración siguiente como
guía para la creación de un fotograma clave.
4. Reduzca CuboCristal en este fotograma clave: con el segundo fotograma
clave seleccionado, reduzca el tamaño de CuboCristal al 90% de su tamaño
total utilizando la Transformación de tamaño.
Presione F5 para ejecutar la aplicación. Mueva el puntero sobre el botón.
Observe que la capa de cristal se reduce en la parte superior del botón.
5. Cree otro desencadenador de eventos y asocie otra animación al mismo:
agreguemos una animación más. Utilice un procedimiento similar al que
empleó para crear la animación del desencadenador de eventos anterior:
a. Cree un nuevo desencadenador de eventos mediante el evento Click.
b. Asocie una nueva escala de tiempo al evento Click.

c. Para esta escala de tiempo, cree dos fotogramas clave, uno a los 0,0
segundos y el otro a los 0,3 segundos.
d. Con el fotograma clave de los 0,3 segundos resaltado, establezca el
Ángulo de giro en 360 grados.

e. Presione F5 para ejecutar la aplicación. Haga clic en el botón. Observe


que la capa de cristal gira sobre sí misma.

Conclusión
Ya ha completado el botón personalizado. Para ello, ha utilizado una plantilla de botón
que se aplicaba a todos los botones de la aplicación. Si sale del modo de edición de
plantillas (consulte la ilustración siguiente) y crea más botones, verá que se parecen y
se comportan como el botón personalizado en lugar de como el botón
predeterminado.
Presione F5 para ejecutar la aplicación. Haga clic en los botones y observe cómo todos
ellos se comportan del mismo modo.
Recuerde que mientras estaba personalizando la plantilla, estableció la propiedad Fill
de RectánguloInterior y la propiedad Stroke de RectánguloExterior en el fondo de
plantilla ({Fondo de TemplateBinding}). Por ello, cuando establezca el color de fondo
de los botones individuales, el fondo que estableció se utilizará para las propiedades
respectivas. Pruebe a cambiar los fondos ahora. En la ilustración siguiente, se utilizan
distintos degradados. Por lo tanto, aunque una plantilla sea útil para realizar una
personalización global de controles como los botones, los controles basados en
plantillas también pueden modificarse para que sean distintos entre sí.

En resumen, durante el proceso de personalización de una plantilla de botón ha


aprendido a hacer lo siguiente en Microsoft Expression Blend:
 Personalizar el aspecto de un control.
 Establecer desencadenadores de propiedad. Los desencadenadores de
propiedad resultan muy útiles ya que pueden utilizarse en la mayoría de los
objetos, no sólo en los controles.
 Establecer desencadenadores de eventos. Los desencadenadores de eventos
resultan muy útiles porque pueden utilizarse en la mayoría de los objetos, no
sólo en los controles.
 Crear animaciones.
 Varios: crear degradados, agregar efectos de mapa de bits, usar
transformaciones y establecer propiedades básicas para los objetos.
Tutorial: Mostrar los datos de
una base de datos de SQL Server
en un control DataGrid
En este tutorial, recuperará datos de una base de datos de SQL Server y mostrará esos
datos en un control DataGrid. Usará ADO.NET Entity Framework para crear las clases
de entidad que representan los datos y usará LINQ para escribir una consulta que
recupera los datos especificados de una clase de entidad.

Requisitos previos
Necesita los componentes siguientes para completar este tutorial:
 Visual Studio 2012.
 Acceso a una instancia en ejecución de SQL Server o SQL Server Express que
tenga adjunta la base de datos de ejemplo AdventureWorksLT2008. La base
de datos AdventureWorksLT2008 se puede descargar desde el sitio web de
CodePlex.
Para crear clases de entidad
1. Cree un nuevo proyecto de aplicación WPF en Visual Basic o C# y asígnele el
nombre DataGridSQLExample.
2. En el Explorador de soluciones, haga clic con el botón secundario en el
proyecto, elija Agregar y seleccione Nuevo elemento.
Aparecerá el cuadro de diálogo Agregar nuevo elemento.
3. En el panel Plantillas instaladas, seleccione Datos y, en la lista de plantillas,
seleccione Modelo de datos de entidad de ADO.NET.
4. Asigne al archivo el nombre AdventureWorksModel.edmx y haga clic en
Agregar.
Aparecerá el Asistente para Entity Data Model.
5. En la pantalla Elegir contenido de Model, seleccione Generar desde la base
de datos y haga clic en Siguiente.
6. En la pantalla Elegir la conexión de datos, proporcione la conexión a la base
de datos AdventureWorksLT2008. Para obtener más información, vea Cuadro
de diálogo Elegir la conexión de datos.
7. Asegúrese de que el nombre sea AdventureWorksLT2008Entities y que la
casilla Guardar configuración de conexión de la entidad en App.Config
como esté activada; a continuación, haga clic en Siguiente.
8. En la pantalla Elija los objetos de base de datos, expanda el nodo Tablas, y
seleccione las tablas Product y ProductCategory.
Puede generar clases de entidad para todas las tablas; sin embargo, en este
ejemplo solo recupera datos de esas dos tablas.
9. Haga clic en Finalizar.
Las entidades Product y ProductCategory se mostrarán en Entity Designer.
Para recuperar y presentar los datos
1. Abra el archivo MainWindow.xaml.
2. Establezca la propiedad Width del control Window en 450.
3. En el editor XAML, agregue la siguiente etiqueta DataGrid entre las etiquetas
<Grid> y </Grid> para agregar un objeto DataGrid denominado dataGrid1.

XAML

<DataGrid Name="dataGrid1" />


4. Seleccione Window.
5. Usando la ventana Propiedades o el editor XAML, cree un controlador de
eventos para Window denominado Window_Loaded para el evento Loaded.
Para obtener más información, vea Cómo: Crear controladores de eventos
simples.
A continuación se muestra el código XAML para MainWindow.xaml.

Nota

Si usa Visual Basic, en la primera línea de MainWindow.xaml,


reemplace x:Class="DataGridSQLExample.MainWindow"
por x:Class="MainWindow".

XAML

<Window x:Class="DataGridSQLExample.MainWindow"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentatio
n"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="450"
Loaded="Window_Loaded">
<Grid>
<DataGrid Name="dataGrid1" />
</Grid>
</Window>
6. Abra el archivo de código subyacente (MainWindow.xaml.vb o
MainWindow.xaml.cs) para Window.
7. Agregue el código siguiente para recuperar solo determinados valores de las
tablas combinadas y establecer la propiedad ItemsSource de DataGrid en los
resultados de la consulta.

C#

using System.Data.Objects;
using System.Linq;
using System.Windows;

namespace DataGridSQLExample
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
AdventureWorksLT2008Entities dataEntities = new
AdventureWorksLT2008Entities();

public MainWindow()
{
InitializeComponent();
}

private void Window_Loaded(object sender,


RoutedEventArgs e)
{
ObjectQuery<Product> products =
dataEntities.Products;

var query =
from product in products
where product.Color == "Red"
orderby product.ListPrice
select new { product.Name, product.Color,
CategoryName = product.ProductCategory.Name, product.ListPrice
};

dataGrid1.ItemsSource = query.ToList();
}
}
}

8. Ejecute el ejemplo.
Debe aparecer un control DataGrid que muestre datos.
MIGRACION E
INTEROPERABILIDAD EN WPF
Tutorial: Hospedar un control de
Windows Forms en WPF
WPF proporciona numerosos controles con un completo conjunto de características.
Sin embargo, en ocasiones puede que prefiera utilizar controles de formularios
Windows Forms en páginas de WPF. Por ejemplo, es posible que disponga de un
importante parque de controles de formularios Windows Forms existentes, o un
control de formularios Windows Forms que proporcione una funcionalidad única.
En este tutorial se muestra cómo hospedar un control
System.Windows.Forms.MaskedTextBox de formularios Windows Forms en una página
de WPF mediante código.
Para ver una lista de código completa de las tareas mostradas en este tutorial, vea
Hosting a Windows Forms Control in WPF Sample.

Requisitos previos
Necesita los componentes siguientes para completar este tutorial:
 Visual Studio 2010.

Hospedar un control de Windows Forms


Para hospedar el control MaskedTextBox
1. Cree un proyecto de aplicación de WPF denominado HostingWfInWpf.
2. Agregue referencias a los siguientes ensamblados.
o WindowsFormsIntegration
o System.Windows.Forms
3. Abra MainWindow.xaml en WPF Designer.
4. Asigne el nombre grid1 al elemento Grid.

XAML
<Grid Name="grid1">

</Grid>

5. En la vista Diseño o en la vista XAML, seleccione el elemento Window.


6. En la ventana Propiedades, haga clic en la pestaña Eventos.
7. Haga doble clic en el evento Loaded.
8. Inserte el código siguiente para controlar el evento Loaded.

private void Window_Loaded(object sender, RoutedEventArgs e)


{
// Create the interop host control.
System.Windows.Forms.Integration.WindowsFormsHost host =
new
System.Windows.Forms.Integration.WindowsFormsHost();

// Create the MaskedTextBox control.


MaskedTextBox mtbDate = new MaskedTextBox("00/00/0000");

// Assign the MaskedTextBox control as the host control's


child.
host.Child = mtbDate;

// Add the interop host control to the Grid


// control's collection of child controls.
this.grid1.Children.Add(host);
}

9. En la parte superior del archivo, agregue Imports o la instrucción using


siguiente.

C#

using System.Windows.Forms;

10. Presione F5 para compilar y ejecutar la aplicación.


Tutorial: Hospedar un control
compuesto de formularios
Windows Forms en WPF
Windows Presentation Foundation (WPF) proporciona un entorno enriquecido para la
creación de 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 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 WPF. Por ejemplo, puede utilizar WPF para
realizar la mayoría de la programación al hospedar los controles DataGridView
especializados.

Este tutorial describe una aplicación que hospeda un control compuesto de


formularios Windows Forms para realizar la entrada de datos en una aplicación de
WPF. 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 WPF en formularios Windows Forms. 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 formularios Windows Forms. La segunda
sección explica en detalle cómo hospedar el control compuesto en una aplicación de
WPF, 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 Windows Forms.
 Implementar la aplicación host de WPF.
Para ver una lista de código completa de las tareas mostradas en este tutorial, vea
Hosting a Windows Forms Composite Control in WPF Sample.
Requisitos previos
Necesita los componentes siguientes para completar este tutorial:
 Visual Studio 2010.

Implementar el control compuesto de Windows


Forms
El control compuesto 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 compuesto de Windows Forms

Crear el proyecto
Para iniciar el proyecto:
1. Inicie Microsoft Visual Studio y abra el cuadro de diálogo Nuevo proyecto.
2. En la categoría de ventana, seleccione la plantilla Biblioteca de controles de
Windows Forms.
3. Denomine el nuevo proyecto MyControls.
4. Para la ubicación, especifique una carpeta de nivel superior con un nombre
adecuado, por ejemplo WpfHostingWindowsFormsControl. 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 está incluida de forma predeterminada, agréguela al proyecto.
 Sistema
 System.Data
 System.Drawing
 System.Windows.Forms
 System.Xml
Agregar controles al formulario
Para agregar controles al formulario:
 Abra MyControl1 en el diseñador.
Agregue cinco controles Label y sus controles TextBox correspondientes, con los
tamaños y la organización indicados en la ilustración anterior, en el formulario. En el
ejemplo, los controles TextBox tienen los nombres siguientes:
 txtName
 txtAddress
 txtCity
 txtState
 txtZip
Agregue dos controles 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 el formulario en la vista de código. 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 el código siguiente a la clase MyControl1.
C#

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 la clase siguiente al formulario.
C#
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 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 código se muestran los controladores de los dos
botones.
Agregue el código siguiente a la clase MyControl1.
C#

private void btnOK_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 btnCancel_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 compilar 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 proyecto.
1. 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
2010/Visual Studio Tools/Símbolo del sistema de Visual Studio. Se iniciará
una ventana de consola con variables de entorno personalizadas.
2. En el símbolo del sistema, utilice el comando cd para ir a la carpeta del
proyecto.
3. Genere un archivo de clave con el nombre MyControls.snk ejecutando el
comando siguiente.
4. Sn.exe -k MyControls.snk
5. 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, a
continuación, haga clic en Propiedades. En el Diseñador de proyectos, haga
clic en la pestaña Firma, active la casilla Firmar el ensamblado y, a
continuación, busque el archivo de clave.
6. Compile la solución. La compilación generará una DLL denominada
MyControls.dll.
Implementar la aplicación host de WPF
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 aplicación WPF. En la ilustración
siguiente se muestra la aplicación acabada.
La aplicación completa, que muestra el control incrustado en la aplicación WPF

Crear el proyecto
Para iniciar el proyecto:
1. Abra Visual Studio y seleccione Nuevo proyecto.
2. En la categoría de ventana, seleccione la plantilla Aplicación WPF.
3. Denomine el nuevo proyecto WpfHost.
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 una referencia al ensamblado WindowsFormsIntegration, que se
denomina WindowsFormsIntegration.dll.
Implementar el diseño básico
La interfaz de usuario (UI) de la aplicación host se implementa en MainWindow.xaml.
Este archivo contiene el marcado de Lenguaje XAML que define el diseño y hospeda el
control de formularios Windows Forms. La aplicación 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 diseño básico se muestra en el código XAML siguiente. El marcado que se necesita
para hospedar MyControl1 se omite en este ejemplo, pero se explicará más adelante.
Reemplace el XAML de MainWindow.xaml con lo siguiente. Si utiliza Visual Basic,
cambie el nombre de la clase a x:Class="MainWindow".
XAML

<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="WpfHost.MainWindow"
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>
</Window>
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 ventana
sin dejar separaciones ni provocar distorsión.
Hospedar el control
La versión editada siguiente del XAML anterior se centra en los elementos que se
necesitan para hospedar MyControl1.
XAML

<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="WpfHost.MainWindow"
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 XAML controlan el hospedaje:
 WindowsFormsHost representa el elemento WindowsFormsHost que permite
hospedar un control de formularios Windows Forms en una aplicación WPF.
 mcl:MyControl1, que representa a MyControl1, se agrega a la colección de
elementos secundarios del elemento WindowsFormsHost. Por consiguiente,
este control de formularios Windows Forms se presenta como parte de la
ventana de WPF y es posible comunicarse con el control desde la aplicación.
Implementar el archivo de código subyacente
El archivo de código subyacente, MainWindow.xaml.vb o MainWindow.xaml.cs,
contiene el código de procedimiento que implementa la funcionalidad de la interfaz
de usuario descrito 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 ventana y adjunta un controlador al evento OnButtonClick del control.
En MainWindow.xaml.vb o MainWindow.xaml.cs, agregue el código siguiente a la clase
MainWindow.

private Application app;


private Window 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 = (Window)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 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 aplicación. En el código
de inicialización se asignan esos valores a las variables globales privadas para su uso
posterior en la aplicación.
Para poder tener un fácil acceso a los tipos de la DLL MyControls, agregue la
siguiente instrucción Imports o using a la parte superior del archivo.
C#

using MyControls;
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 MainWindow.
C#

//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. Por consiguiente, puede cambiar el aspecto del control para
adaptarlo mejor al estilo de la aplicación. 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.
Agregue el código siguiente a la clase MainWindow.
C#

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

Compile y ejecute la aplicación. Agregue texto en el control compuesto de Windows


Forms y, a continuación, haga clic en Aceptar. El texto aparece en las etiquetas. Haga
clic en los distintos botones de radio para ver el efecto en el control.
Tutorial: Hospedar un control
compuesto de WPF en
formularios Windows Forms
Windows Presentation Foundation (WPF) proporciona un entorno enriquecido para la
creación de aplicaciones. Sin embargo, cuando se tiene una inversión sustancial en
código formularios Windows Forms, puede ser más efectivo extender la aplicación
formularios 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 formularios 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 formularios 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 formularios 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.

Requisitos previos
Necesita los componentes siguientes para completar este tutorial:
 Visual Studio 2010.
Implementar el control compuesto de WPF

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

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 interfaz de usuario (UI) del control compuesto se implementa mediante
Lenguaje XAML. El control compuesto interfaz de usuario consta de cinco
elementosTextBox. 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 interfaz de usuario 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
elementoGrid.
En MyControl1.xaml, reemplace el XAML existente por el siguiente XAML.
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 interfaz de usuario 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
atributoColumnSpanProperty. 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.
XAML

<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.
XAML

<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 formularios 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 interfaz de usuario 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.
C#

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.
C#

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.
C#

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.
C#

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.


Implementar la aplicación host de formularios
de Windows Forms.
La aplicación host de formularios Windows Forms utiliza un objeto ElementHost para
hospedar el control compuesto de WPF. La aplicación controla el
eventoOnButtonClick 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

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.
o PresentationCore
o PresentationFramework
o System.Xaml
o WindowsBase
o 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.

Name 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 Name 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 Name 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.
C#

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

C#

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.


C#

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
controlesLabel 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.
C#

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 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
eventosCheckedChanged por el siguiente código.
C#

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 distintos botones de radio para ver el
efecto en el control compuesto de WPF.
Tutorial: Organizar controles de
formularios Windows Forms en WPF
En este tutorial se muestra cómo utilizar las características de diseño de WPF para
organizar controles de formularios Windows Forms en una aplicación híbrida.
Las tareas ilustradas en este tutorial incluyen:
 Crear el proyecto.
 Utilizar la configuración de diseño predeterminada.
 Ajustar el tamaño al contenido.
 Utilizar posiciones absolutas.
 Especificar explícitamente el tamaño.
 Establecer las propiedades de diseño.
 Entender las limitaciones del orden z.
 Acoplamiento.
 Establecer la visibilidad.
 Hospedar un control que no se ajusta.
 Cambiar la escala.
 Girar.
 Establecer relleno y márgenes.
 Utilizar contenedores de diseño dinámico.
Para ver una lista de código completa de las tareas mostradas en este tutorial, vea
Arranging Windows Forms Controls in WPF Sample.
Cuando termine, comprenderá las características de diseño de formularios Windows
Forms en aplicaciones basadas en WPF.

Requisitos previos
Necesita los componentes siguientes para completar este tutorial:
 Visual Studio 2010.

Crear el proyecto
Para crear y configurar el proyecto
1. Cree un proyecto de aplicación de WPF denominado WpfLayoutHostingWf.
2. En el Explorador de soluciones, agregue referencias a los ensamblados
siguientes.
o WindowsFormsIntegration
o System.Windows.Forms
o System.Drawing
3. Haga doble clic en MainWindow.xaml para abrirlo en la vista XAML.
4. En el elemento Window, agregue la siguiente asignación de espacio de
nombres formularios Windows Forms.

XAML

xmlns:wf="clr-
namespace:System.Windows.Forms;assembly=System.Windows.Forms"
5. En el elemento Grid, establezca la propiedad ShowGridLines en true y defina
cinco filas y tres columnas.

XAML

<Grid ShowGridLines="true">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>

<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>

Utilizar la configuración de diseño


predeterminada
De manera predeterminada, el elemento WindowsFormsHost administra el diseño
para el control de formularios Windows Forms hospedado.
Para utilizar la configuración de diseño predeterminada
1. Copie el XAML siguiente en el elemento Grid.
XAML

<!-- Default layout. -->


<Canvas Grid.Row="0" Grid.Column="0">
<WindowsFormsHost Background="Yellow">
<wf:Button Text="Windows Forms control" FlatStyle="Flat"/>
</WindowsFormsHost>
</Canvas>

2. Presione F5 para compilar y ejecutar la aplicación. Aparecerá el control


System.Windows.Forms.Button de formularios Windows Forms en el objeto
Canvas. El control hospedado cambiará de tamaño de acuerdo con su
contenido; el tamaño del elemento WindowsFormsHost se ajustará para alojar
el control hospedado.

Ajustar el tamaño al contenido


El elemento WindowsFormsHost garantiza que el tamaño del control hospedado se
ajuste para mostrar correctamente su contenido.
Para ajustar el tamaño al contenido
1. Copie el XAML siguiente en el elemento Grid.

XAML

<!-- Sizing to content. -->


<Canvas Grid.Row="1" Grid.Column="0">
<WindowsFormsHost Background="Orange">
<wf:Button Text="Windows Forms control with more content"
FlatStyle="Flat"/>
</WindowsFormsHost>
</Canvas>

<Canvas Grid.Row="2" Grid.Column="0">


<WindowsFormsHost FontSize="24" Background="Yellow">
<wf:Button Text="Windows Forms control" FlatStyle="Flat"/>
</WindowsFormsHost>
</Canvas>
2. Presione F5 para compilar y ejecutar la aplicación. El tamaño de los dos
nuevos controles de botón se ajusta para mostrar correctamente la cadena de
texto más larga y el tamaño de fuente mayor, y se cambia el tamaño de los
elementos WindowsFormsHost para alojar los controles hospedados.

Utilizar posiciones absolutas


Puede utilizar posiciones absolutas para colocar el elemento WindowsFormsHost en
cualquier ubicación de la interfaz de usuario.
Para utilizar posiciones absolutas
1. Copie el XAML siguiente en el elemento Grid.

XAML

<!-- Absolute positioning. -->


<Canvas Grid.Row="3" Grid.Column="0">
<WindowsFormsHost Canvas.Top="20" Canvas.Left="20"
Background="Yellow">
<wf:Button Text="Windows Forms control with absolute
positioning" FlatStyle="Flat"/>
</WindowsFormsHost>
</Canvas>

2. Presione F5 para compilar y ejecutar la aplicación. El elemento


WindowsFormsHost se coloca a 20 píxeles del lado superior de la celda de la
cuadrícula y a 20 píxeles del lado izquierdo.

Especificar explícitamente el tamaño


Puede especificar el tamaño del elemento WindowsFormsHost utilizando las
propiedades Width y Height.
Para especificar explícitamente el tamaño
1. Copie el XAML siguiente en el elemento Grid.

XAML

<!-- Explicit sizing. -->


<Canvas Grid.Row="4" Grid.Column="0">
<WindowsFormsHost Width="50" Height="70" Background="Yellow">
<wf:Button Text="Windows Forms control" FlatStyle="Flat"/>
</WindowsFormsHost>
</Canvas>

2. Presione F5 para compilar y ejecutar la aplicación. El elemento


WindowsFormsHost se establece en un tamaño de 50 píxeles de ancho por 70
píxeles de alto, menor que los valores de diseño predeterminados. El
contenido del control de formularios Windows Forms se reorganiza en
consecuencia.

Establecer las propiedades de diseño


Establezca siempre las propiedades del control hospedado relacionadas con el diseño
mediante las propiedades del elemento WindowsFormsHost. Si establece
directamente las propiedades de diseño del control hospedado, se producirán
resultados imprevistos.
Establecer las propiedades relacionadas con el diseño del control hospedado en XAML
no tiene ningún efecto.
Para ver los efectos de establecer las propiedades en el control
hospedado
1. Copie el XAML siguiente en el elemento Grid.

XAML

<!-- Setting hosted control properties directly. -->


<Canvas Grid.Row="0" Grid.Column="1">
<WindowsFormsHost Width="160" Height="50"
Background="Yellow">
<wf:Button Name="button1" Click="button1_Click" Text="Click
me" FlatStyle="Flat" BackColor="Green"/>
</WindowsFormsHost>
</Canvas>

2. En el Explorador de soluciones haga doble clic en MainWindow.xaml. vb o


MainWindow.xaml.cs para abrirlo en el Editor de código.
3. Copie el código siguiente en la definición de la clase MainWindow.

C#
private void button1_Click(object sender, EventArgs e )
{
System.Windows.Forms.Button b = sender as
System.Windows.Forms.Button;

b.Top = 20;
b.Left = 20;
}

4. Presione F5 para compilar y ejecutar la aplicación.


5. Haga clic en el botón Click me. El controlador de eventos button1_Click
establece las propiedades Top y Left del control hospedado. Esto hace que el
control hospedado cambie de posición dentro del elemento
WindowsFormsHost. El host mantiene la misma área de pantalla, pero el
control hospedado se recorta. En lugar de ello, el control hospedado siempre
debe rellenar el elemento WindowsFormsHost.

Entender las limitaciones del orden z


De forma predeterminada, los elementos visibles de WindowsFormsHost siempre se
dibujan encima de otros elementos de WPF , y no están afectados por orden z. Para
habilitar la ordenación z, establezca IsRedirected de
la propiedad de
WindowsFormsHost en true y la propiedad de CompositionMode a Full o a
OutputOnly.
Para ver el comportamiento predeterminado del orden z
1. Copie el XAML siguiente en el elemento Grid.

XAML

<!-- Z-order demonstration. -->


<Canvas Grid.Row="1" Grid.Column="1">
<WindowsFormsHost Canvas.Top="20" Canvas.Left="20"
Background="Yellow">
<wf:Button Text="Windows Forms control" FlatStyle="Flat"/>
</WindowsFormsHost>
<Label Content="A WPF label" FontSize="24"/>
</Canvas>
2. Presione F5 para compilar y ejecutar la aplicación. El elemento
WindowsFormsHost se pinta encima del elemento de etiqueta.
Para ver el comportamiento del orden z cuando IsRedirected es
true
 Reemplace el ejemplo anterior del orden z con el XAML siguiente.

XAML

<!-- Z-order demonstration. -->


<Canvas Grid.Row="1" Grid.Column="1">
<WindowsFormsHost IsRedirected="True" CompositionMode="Full"
Canvas.Top="20" Canvas.Left="20" Background="Yellow">
<wf:Button Text="Windows Forms control" FlatStyle="Flat"/>
</WindowsFormsHost>
<Label Content="A WPF label" FontSize="24"/>
</Canvas>

Presione F5 para compilar y ejecutar la aplicación. El elemento de la etiqueta


se pinta encima del elemento de WindowsFormsHost .

Acoplamiento
El elemento WindowsFormsHost admite el acoplamiento de WPF. Establezca la
propiedad Dock adjunta para acoplar el control hospedado en un elemento
DockPanel.
Para acoplar un control hospedado
1. Copie el XAML siguiente en el elemento Grid.

XAML

<!-- Docking a WindowsFormsHost element. -->


<DockPanel LastChildFill="false" Grid.Row="2" Grid.Column="1">
<WindowsFormsHost DockPanel.Dock="Right" Canvas.Top="20"
Canvas.Left="20" Background="Yellow">
<wf:Button Text="Windows Forms control" FlatStyle="Flat"/>
</WindowsFormsHost>
</DockPanel>
2. Presione F5 para compilar y ejecutar la aplicación. El elemento
WindowsFormsHost se acopla en el lado derecho del elemento DockPanel.

Establecer la visibilidad
Puede hacer que el control de formularios Windows Forms sea invisible o contraerlo
estableciendo la propiedad Visibility del elemento WindowsFormsHost. Cuando un
control no está visible, no se muestra, pero ocupa espacio en el diseño. Cuando se
contrae un control, no se muestra, ni ocupa el espacio en el diseño.
Para establecer la visibilidad de un control hospedado
1. Copie el XAML siguiente en el elemento Grid.

XAML

<!-- Setting Visibility to hidden and collapsed. -->


<StackPanel Grid.Row="3" Grid.Column="1">
<Button Name="button2" Click="button2_Click" Content="Click
to make invisible" Background="OrangeRed"/>
<WindowsFormsHost Name="host1" Background="Yellow">
<wf:Button Text="Windows Forms control" FlatStyle="Flat"/>
</WindowsFormsHost>
<Button Name="button3" Click="button3_Click" Content="Click
to collapse" Background="OrangeRed"/>
</StackPanel>

2. En MainWindow.xaml.vb o MainWindow.xaml.cs, copie el código siguiente en


la definición de clase.
private void button2_Click(object sender, EventArgs e)
{
this.host1.Visibility = Visibility.Hidden;
}

private void button3_Click(object sender, EventArgs e)


{
this.host1.Visibility = Visibility.Collapsed;
}

3. Presione F5 para compilar y ejecutar la aplicación.


4. Haga clic en el botón Click to make invisible para hacer invisible el elemento
WindowsFormsHost.
5. Haga clic en el botón Click to collapse para ocultar completamente el
elemento WindowsFormsHost del diseño. Cuando se contrae el control de
formularios Windows Forms, los elementos circundantes se reorganizan para
ocupar su espacio.

Hospedar un control que no se ajusta


Algunos controles de formularios Windows Forms tienen un tamaño fijo y no se
ajustan para rellenar el espacio disponible en el diseño. Por ejemplo, el
controlMonthCalendar muestra un mes en un espacio fijo.
Para hospedar un control que no se ajusta
1. Copie el XAML siguiente en el elemento Grid.

XAML

<!-- Hosting a control that does not stretch. -->


<!-- The MonthCalendar has a discrete size. -->
<StackPanel Grid.Row="4" Grid.Column="1">
<Label Content="A WPF element" Background="OrangeRed"/>
<WindowsFormsHost Background="Yellow">
<wf:MonthCalendar/>
</WindowsFormsHost>
<Label Content="Another WPF element" Background="OrangeRed"/>
</StackPanel>

2. Presione F5 para compilar y ejecutar la aplicación. El elemento


WindowsFormsHost se centra en la fila de la cuadrícula, pero no se ajusta para
rellenar el espacio disponible. Si la ventana es lo bastante grande, puede que
vea dos o más meses mostrados por el control MonthCalendar hospedado,
pero éstos están centrados en la fila. El motor de diseño de WPF centra los
elementos cuyo tamaño no se puede ajustar para rellenar el espacio
disponible.

Ajustar la escala
A diferencia de los elementos de WPF, la escala de la mayoría de los controles de
formularios Windows Forms no se puede cambiar continuamente. De forma
predeterminada, el elemento de WindowsFormsHost escala el control hospedado
cuando es posible. Para habilitar el ajuste de escala hechos y derecho, establezca la
IsRedirected de WindowsFormsHost en true y la propiedad de
propiedad de
CompositionMode a Full o a OutputOnly.
Escalar un control hospedado utilizando el comportamiento
predeterminado
1. Copie el XAML siguiente en el elemento Grid.

XAML

<!-- Scaling transformation. -->


<StackPanel Grid.Row="0" Grid.Column="2">

<StackPanel.RenderTransform>
<ScaleTransform CenterX="0" CenterY="0" ScaleX="0.5"
ScaleY="0.5" />
</StackPanel.RenderTransform>

<Label Content="A WPF UIElement" Background="OrangeRed"/>

<WindowsFormsHost Background="Yellow">
<wf:Button Text="Windows Forms control" FlatStyle="Flat"/>
</WindowsFormsHost>

<Label Content="Another WPF UIElement"


Background="OrangeRed"/>

</StackPanel>

2. Presione F5 para compilar y ejecutar la aplicación. La escala del control


hospedado y de los elementos que lo rodean se ajusta mediante un factor de
0,5. Sin embargo, no se ajusta el tamaño de la fuente del control hospedado.
Escalar un control hospedado estableciendo IsRedirected en true
1. Reemplace el ejemplo anterior de escala con el XAML siguiente.

XAML

<!-- Scaling transformation. -->


<StackPanel Grid.Row="0" Grid.Column="2">
<StackPanel.RenderTransform>
<ScaleTransform CenterX="0" CenterY="0" ScaleX="0.5"
ScaleY="0.5" />
</StackPanel.RenderTransform>

<Label Content="A WPF UIElement" Background="OrangeRed"/>

<WindowsFormsHost Background="Yellow" IsRedirected="True"


CompositionMode="Full">
<wf:Button Text="Windows Forms control" FlatStyle="Flat"/>
</WindowsFormsHost>

<Label Content="Another WPF UIElement"


Background="OrangeRed"/>

</StackPanel>

2. Presione F5 para compilar y ejecutar la aplicación. El control hospedado, los


elementos que lo rodean, y la fuente del control hospedado son escalados por
un factor de 0,5.

Girar
A diferencia de los elementos de WPF, los controles de formularios Windows Forms no
admiten el giro. De forma predeterminada, el elemento de WindowsFormsHost no gira
con otros elementos de WPF cuando se aplica una transformación de giro. Cualquier
valor de giro distinto de 180 grados provoca el evento LayoutError. Para habilitar girar
IsRedirected de WindowsFormsHost
a cualquier ángulo, establezca la propiedad de
en true y la propiedad de CompositionMode a Full o a OutputOnly.
Para ver el efecto del giro en una aplicación híbrida
1. Copie el XAML siguiente en el elemento Grid.

XAML

<!-- Rotation transformation. -->


<StackPanel Grid.Row="1" Grid.Column="2">

<StackPanel.RenderTransform>
<RotateTransform CenterX="200" CenterY="50" Angle="180" />
</StackPanel.RenderTransform>

<Label Content="A WPF element" Background="OrangeRed"/>

<WindowsFormsHost Background="Yellow">
<wf:Button Text="Windows Forms control" FlatStyle="Flat"/>
</WindowsFormsHost>

<Label Content="Another WPF element" Background="OrangeRed"/>

</StackPanel>

2. Presione F5 para compilar y ejecutar la aplicación. No se gira el control


hospedado, pero los elementos que lo rodean se giran en un ángulo de 180
grados. Es posible que deba cambiar de tamaño la ventana para ver los
elementos.
Para ver el efecto del giro en una aplicación híbrida cuando
IsRedirected es true
1. Reemplace el ejemplo anterior de giro con el XAML siguiente.

<!-- Rotation transformation. -->


<StackPanel Grid.Row="1" Grid.Column="2">

<StackPanel.RenderTransform>
<RotateTransform CenterX="200" CenterY="50" Angle="180" />
</StackPanel.RenderTransform>

<Label Content="A WPF element" Background="OrangeRed"/>

<WindowsFormsHost Background="Yellow" IsRedirected="True"


CompositionMode="Full">
<wf:Button Text="Windows Forms control" FlatStyle="Flat"/>
</WindowsFormsHost>

<Label Content="Another WPF element" Background="OrangeRed"/>

</StackPanel>
2. Presione F5 para compilar y ejecutar la aplicación. Gira el control hospedado.
Observe que la propiedad de Angle se puede establecer en cualquier valor. Es
posible que deba cambiar de tamaño la ventana para ver los elementos.

Establecer relleno y márgenes


El relleno y los márgenes en el diseño de WPF son similares a los de formularios
Windows Forms. Basta con establecer las propiedades Padding y Margin del
elementoWindowsFormsHost.
Para establecer el relleno y los márgenes para un control
hospedado
1. Copie el XAML siguiente en el elemento Grid.

XAML

<!-- Padding. -->


<Canvas Grid.Row="2" Grid.Column="2">
<WindowsFormsHost Padding="0, 20, 0, 0" Background="Yellow">
<wf:Button Text="Windows Forms control with padding"
FlatStyle="Flat"/>
</WindowsFormsHost>
</Canvas>

<!-- Margin. -->


<Canvas Grid.Row="3" Grid.Column="2">
<WindowsFormsHost Margin="20, 20, 0, 0" Background="Yellow">
<wf:Button Text="Windows Forms control with margin"
FlatStyle="Flat"/>
</WindowsFormsHost>
</Canvas>

2. Presione F5 para compilar y ejecutar la aplicación. La configuración de los


márgenes y del relleno se aplica a los controles de formularios Windows
Forms hospedados de la misma manera que se aplicarían en formularios
Windows Forms.
Utilizar contenedores de diseño dinámico
formularios Windows Forms proporciona dos contenedores de diseño dinámico,
FlowLayoutPanel y TableLayoutPanel. También puede utilizar estos contenedores en
diseños de WPF.
Para utilizar un contenedor de diseño dinámico
1. Copie el XAML siguiente en el elemento Grid.

XAML

<!-- Flow layout. -->


<DockPanel Grid.Row="4" Grid.Column="2">
<WindowsFormsHost Name="flowLayoutHost" Background="Yellow">
<wf:FlowLayoutPanel/>
</WindowsFormsHost>
</DockPanel>

2. En MainWindow.xaml.vb o MainWindow.xaml.cs, copie el código siguiente en


la definición de clase.

private void InitializeFlowLayoutPanel()


{
System.Windows.Forms.FlowLayoutPanel flp =
this.flowLayoutHost.Child as
System.Windows.Forms.FlowLayoutPanel;

flp.WrapContents = true;

const int numButtons = 6;

for (int i = 0; i < numButtons; i++)


{
System.Windows.Forms.Button b = new
System.Windows.Forms.Button();
b.Text = "Button";
b.BackColor = System.Drawing.Color.AliceBlue;
b.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
flp.Controls.Add(b);
}
}

3. Agregue una llamada al método InitializeFlowLayoutPanel en el


constructor.

public MainWindow()
{
InitializeComponent();

this.InitializeFlowLayoutPanel();
}

4. Presione F5 para compilar y ejecutar la aplicación. El elemento


WindowsFormsHost rellena DockPanel, y FlowLayoutPanel organiza sus
controles secundarios de acuerdo con la propiedad FlowDirection
predeterminada.
Tutorial: Enlazar a datos en
aplicaciones híbridas
Enlazar un origen de datos a un control es esencial para proporcionar a los usuarios
acceso a los datos subyacentes, tanto si se está utilizando formularios Windows Forms
como WPF. Este tutorial muestra cómo puede utilizar el enlace de datos en
aplicaciones híbridas que incluyan tanto controles formularios Windows Forms como
controles WPF.
Las tareas ilustradas en este tutorial incluyen:
 Crear el proyecto.
 Definir la plantilla de datos.
 Especificar el diseño del formulario.
 Especificar los enlaces de datos.
 Mostrar los datos utilizando interoperatividad.
 Agregar el origen de datos al proyecto.
 Establecer el enlace con el origen de datos.
Para obtener una lista de código completa de las tareas ilustradas en este tutorial, vea
Data Binding in Hybrid Applications Sample.
Cuando termine, comprenderá las características de enlace de datos en aplicaciones
híbridas.

Requisitos previos
Necesita los componentes siguientes para completar este tutorial:
 Visual Studio 2010.
 Acceso a la base de datos de ejemplo Northwind ejecutándose en SQL Server.

Crear el proyecto
Para crear y configurar el proyecto
1. Cree un proyecto Aplicación WPF denominado
WPFWithWFAndDatabinding.
2. En el Explorador de soluciones, agregue referencias a los ensamblados
siguientes.
o WindowsFormsIntegration
o System.Windows.Forms
3. Abra MainWindow.xaml en WPF Designer.
4. En el elemento Window, agregue la siguiente asignación de espacio de
nombres formularios Windows Forms.

XAML

xmlns:wf="clr-
namespace:System.Windows.Forms;assembly=System.Windows.Forms"
5. Nombre el elemento GridmainGrid predeterminado asignando la propiedad
Name.

XAML

<Grid x:Name="mainGrid">

Definir la plantilla de datos


La lista maestra de clientes se muestra en un control ListBox. En el ejemplo de código
siguiente se define un objeto DataTemplate denominado ListItemsTemplate que
controla el árbol visual del control ListBox. Este objeto DataTemplate se asigna a la
propiedad ItemTemplate del control ListBox.
Para definir la plantilla de datos
 Copie el siguiente código XAML en la declaración del elemento Grid.

XAML

<Grid.Resources>
<DataTemplate x:Key="ListItemsTemplate">
<TextBlock Text="{Binding
Path=ContactName}"/>
</DataTemplate>
</Grid.Resources>

Especificar el diseño del formulario


El diseño del formulario lo define una cuadrícula con tres filas y tres columnas. Se
proporcionan controles Label para identificar cada columna de la tabla Customers.
Para configurar el diseño de la cuadrícula
 Copie el siguiente código XAML en la declaración del elemento Grid.

XAML

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

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

Para configurar los controles de etiqueta


 Copie el siguiente código XAML en la declaración del elemento Grid.

XAML

<StackPanel Orientation="Vertical" Grid.Row="0"


Grid.Column="1">
<Label Margin="20,38,5,2">First
Name:</Label>
<Label Margin="20,0,5,2">Company
Name:</Label>
<Label Margin="20,0,5,2">Phone:</Label>
<Label Margin="20,0,5,2">Address:</Label>
<Label Margin="20,0,5,2">City:</Label>
<Label Margin="20,0,5,2">Region:</Label>
<Label Margin="20,0,5,2">Postal
Code:</Label>
</StackPanel>
Especificar enlaces de datos
La lista maestra de clientes se muestra en un control ListBox. El objeto
ListItemsTemplate asociado enlaza un control TextBlock al campo ContactName de
la base de datos.
Los detalles de cada registro de cliente se muestran en varios controles TextBox.
Para especificar enlaces de datos
 Copie el siguiente código XAML en la declaración del elemento Grid.
La clase Binding enlaza los controles TextBox a los campos adecuados de la
base de datos.

XAML

<StackPanel Orientation="Vertical" Grid.Row="0"


Grid.Column="0">
<Label Margin="20,5,5,0">List of
Customers:</Label>
<ListBox x:Name="listBox1" Height="200"
Width="200" HorizontalAlignment="Left"
ItemTemplate="{StaticResource
ListItemsTemplate}" IsSynchronizedWithCurrentItem="True"
Margin="20,5,5,5"/>
</StackPanel>

<StackPanel Orientation="Vertical" Grid.Row="0"


Grid.Column="2">
<TextBox Margin="5,38,5,2" Width="200"
Text="{Binding Path=ContactName}"/>
<TextBox Margin="5,0,5,2" Width="200"
Text="{Binding Path=CompanyName}"/>
<TextBox Margin="5,0,5,2" Width="200"
Text="{Binding Path=Phone}"/>
<TextBox Margin="5,0,5,2" Width="200"
Text="{Binding Path=Address}"/>
<TextBox Margin="5,0,5,2" Width="200"
Text="{Binding Path=City}"/>
<TextBox Margin="5,0,5,2" Width="30"
HorizontalAlignment="Left" Text="{Binding Path=Region}"/>
<TextBox Margin="5,0,5,2" Width="50"
HorizontalAlignment="Left" Text="{Binding Path=PostalCode}"/>
</StackPanel>

Mostrar datos utilizando interoperatividad.


Los pedidos correspondientes al cliente seleccionado se muestran en un control
System.Windows.Forms.DataGridView denominado dataGridView1. El
controldataGridView1 se enlaza al origen de datos en el archivo de código
subyacente. Un control WindowsFormsHost es el elemento primario de este control de
formularios Windows Forms.
Para mostrar datos en el control DataGridView
 Copie el siguiente código XAML en la declaración del elemento Grid.

XAML

<WindowsFormsHost Grid.Row="1" Grid.Column="0"


Grid.ColumnSpan="3" Margin="20,5,5,5" Height="300">
<wf:DataGridView x:Name="dataGridView1"/>
</WindowsFormsHost>

Agregar el origen de datos al proyecto


Con Visual Studio, puede agregar con facilidad un origen de datos al proyecto. Este
procedimiento agrega un conjunto de datos fuertemente tipado al proyecto. También
se agregan otras diversas clases de soporte, tales como adaptadores de tabla para
cada una de las tablas elegidas.
Para agregar el origen de datos
1. En el menú Datos, seleccione Agregar nuevo origen de datos.
2. En el Asistente para la configuración de orígenes de datos, cree una
conexión a la base de datos Northwind utilizando un conjunto de datos. Para
obtener más información, vea Cómo: Conectarse a los datos de una base de
datos.
3. Cuando se lo pida el Asistente para la configuración de orígenes de datos,
guarde la cadena de conexión como NorthwindConnectionString.
4. Cuando le pidan que elija los objetos de base de datos, seleccione las tablas
Customers y Orders, y asigne el nombre NorthwindDataSet al conjunto de
datos generado.

Establecer el enlace con el origen de datos


El componente System.Windows.Forms.BindingSource proporciona una interfaz
uniforme para el origen de datos de la aplicación. El enlace al origen de datos se
implementa en el archivo de código subyacente.
Para enlazar con el origen de datos
1. Abra el archivo de código subyacente, que se denomina MainWindow.xaml.vb
o MainWindow.xaml.cs.
2. Copie el código siguiente en la definición de la clase MainWindow.
Este código declara el componente BindingSource y las clases auxiliares
asociadas que conectan con la base de datos.

private System.Windows.Forms.BindingSource nwBindingSource;


private NorthwindDataSet nwDataSet;
private NorthwindDataSetTableAdapters.CustomersTableAdapter
customersTableAdapter =
new NorthwindDataSetTableAdapters.CustomersTableAdapter();
private NorthwindDataSetTableAdapters.OrdersTableAdapter
ordersTableAdapter =
new NorthwindDataSetTableAdapters.OrdersTableAdapter();

3. Copie el código siguiente en el constructor.


Este código crea e inicializa el componente BindingSource.

public MainWindow()
{
InitializeComponent();

// Create a DataSet for the Customers data.


this.nwDataSet = new NorthwindDataSet();
this.nwDataSet.DataSetName = "nwDataSet";

// Create a BindingSource for the Customers data.


this.nwBindingSource = new
System.Windows.Forms.BindingSource();
this.nwBindingSource.DataMember = "Customers";
this.nwBindingSource.DataSource = this.nwDataSet;
}

4. Abra MainWindow.xaml.
5. En la vista Diseño o en la vista XAML, seleccione el elemento Window.
6. En la ventana Propiedades, haga clic en la pestaña Eventos.
7. Haga doble clic en el evento Loaded.
8. Copie el código siguiente en el controlador de eventos Loaded.
Este código asigna el componente BindingSource como el contexto de datos y
rellena los objetos de adaptador Customers y Orders.

private void Window_Loaded(object sender, RoutedEventArgs e)


{
// Fill the Customers table adapter with data.
this.customersTableAdapter.ClearBeforeFill = true;
this.customersTableAdapter.Fill(this.nwDataSet.Customers);

// Fill the Orders table adapter with data.


this.ordersTableAdapter.Fill(this.nwDataSet.Orders);

// Assign the BindingSource to


// the data context of the main grid.
this.mainGrid.DataContext = this.nwBindingSource;

// Assign the BindingSource to


// the data source of the list box.
this.listBox1.ItemsSource = this.nwBindingSource;

// Because this is a master/details form, the DataGridView


// requires the foreign key relating the tables.
this.dataGridView1.DataSource = this.nwBindingSource;
this.dataGridView1.DataMember = "FK_Orders_Customers";

// Handle the currency management aspect of the data


models.
// Attach an event handler to detect when the current item
// changes via the WPF ListBox. This event handler
synchronizes
// the list collection with the BindingSource.
//

BindingListCollectionView cv =
CollectionViewSource.GetDefaultView(
this.nwBindingSource) as BindingListCollectionView;

cv.CurrentChanged += new EventHandler(WPF_CurrentChanged);


}

9. Copie el código siguiente en la definición de la clase MainWindow.


Este método administra el evento CurrentChanged y actualiza el elemento
actual del enlace de datos.

// This event handler updates the current item


// of the data binding.
void WPF_CurrentChanged(object sender, EventArgs e)
{
BindingListCollectionView cv = sender as
BindingListCollectionView;
this.nwBindingSource.Position = cv.CurrentPosition;
}

10. Presione F5 para compilar y ejecutar la aplicación.

Вам также может понравиться