Tutorial: Introducción a WPF

En este tutorial se proporciona una introducción al desarrollo de aplicaciones de Windows Presentation Foundation (WPF), que incluye los elementos comunes a la mayoría de las aplicaciones de WPF: marcado Extensible Application Markup Language (XAML), código subyacente, definiciones de aplicación, controles, diseño, enlace de datos y estilos.

Este tutorial le guiará a lo largo del desarrollo de una aplicación básica de WPF mediante los pasos siguientes.

  • Definir XAML para diseñar la apariencia de la user interface (UI) de la aplicación.

  • Escribir código que determine el comportamiento de la aplicación.

  • Crear una definición de aplicación para administrar la aplicación.

  • Agregar controles y crear el diseño para crear la UI de la aplicación.

  • Crear estilos que aporten una apariencia coherente a toda la UI de una aplicación.

  • Enlazar la UI a datos para rellenar la UI a partir de datos y mantener los datos sincronizados con la UI.

Cuando termine el tutorial, habrá generado una aplicación independiente de Windows que permitirá a los usuarios ver los informes de gastos de las personas seleccionadas. La aplicación constará de varias páginas de WPF hospedadas en una ventana del estilo del explorador.

El código de ejemplo que se utiliza para compilar este tutorial está disponible para Microsoft Visual Basic y C#; vea Introduction to Building WPF Applications.

Requisitos previos

Necesita los componentes siguientes para completar este tutorial:

  • Visual Studio 2010

Para obtener más información sobre cómo instalar Visual Studio, vea Instalar Visual Studio.

Crear el proyecto de aplicación

En esta sección, creará la infraestructura de la aplicación, que incluye una definición de aplicación, dos páginas y una imagen.

  1. Cree un nuevo proyecto de aplicación WPF en Visual Basic o Visual C# denominado ExpenseIt. Para obtener más información, vea Cómo: Crear un nuevo proyecto de aplicación de WPF.

    NotaNota

    En este tutorial se utiliza el control DataGrid que está disponible en .NET Framework 4.Asegúrese de que el proyecto tiene como destino .NET Framework 4.Para obtener más información, vea Cómo: Elegir perfil o versión de destino de .NET Framework.

  2. Abra Application.xaml (Visual Basic) o App.xaml (C#).

    Este archivo XAML define una aplicación WPF y los recursos de la aplicación. También se utiliza este archivo para especificar la UI que se muestra automáticamente cuando se inicia la aplicación; en este caso, MainWindow.xaml.

    Su XAML se debería parecer a lo siguiente en Visual Basic:

    <Application x:Class="Application"
        xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
        StartupUri="MainWindow.xaml">
        <Application.Resources>
    
        </Application.Resources>
    </Application>
    

    O así en C#:

    <Application x:Class="ExpenseIt.App"
         xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
         StartupUri="MainWindow.xaml">
        <Application.Resources>
    
        </Application.Resources>
    </Application>
    
  3. Abra MainWindow.xaml.

    Este archivo de código XAML es la ventana principal de la aplicación y muestra contenido creado en páginas. La clase Window define las propiedades de una ventana, como su título, tamaño o icono, y controla los eventos, como cerrarse u ocultarse.

  4. Cambie el elemento Window por NavigationWindow.

    Esta aplicación navegará a contenido diferente según la interacción del usuario. Por consiguiente, Window principal necesita cambiar a NavigationWindow. NavigationWindow hereda todas las propiedades de Window. El elemento NavigationWindow del archivo XAML crea una instancia de la clase NavigationWindow. Para obtener más información, consulte Información general sobre navegación.

  5. Cambie las siguientes propiedades en el elemento NavigationWindow:

    • Establezca la propiedad Title en "ExpenseIt".

    • Establezca la propiedad Width en 500 píxeles.

    • Establezca la propiedad Height en 350 píxeles.

    • Quite los elementos Grid entre las etiquetas NavigationWindow.

    Su XAML se debería parecer a lo siguiente en Visual Basic:

    <NavigationWindow x:Class="MainWindow"
        xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
        Title="ExpenseIt" Height="350" Width="500">
    
    </NavigationWindow>
    

    O así en C#:

    <NavigationWindow x:Class="ExpenseIt.MainWindow"
        xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
        Title="ExpenseIt" Height="350" Width="500">
    
    </NavigationWindow>
    
  6. Abra MainWindow.xaml.vb o MainWindow.xaml.cs.

    Este archivo es un archivo de código subyacente que contiene el código para controlar los eventos declarados en MainWindow.xaml. Este archivo contiene una clase parcial para la ventana definida en XAML.

  7. Si está utilizando C#, cambie la clase MainWindow para que se derive de NavigationWindow.

    En Visual Basic, esto sucede automáticamente al cambiar la ventana en XAML.

    El código debe ser similar al que se muestra a continuación.

    Class MainWindow
    
    End Class
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    
    namespace ExpenseIt
    {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow : NavigationWindow
        {
            public MainWindow()
            {
                InitializeComponent();
            }
        }
    }
    

Agregar archivos a la aplicación

En esta sección, agregará dos páginas y una imagen a la aplicación.

  1. Agregue una nueva página (WPF) al proyecto denominada ExpenseItHome.xaml. Para obtener más información, consulte Cómo: Agregar nuevos elementos a un proyecto de WPF.

    Esta página es la primera página que se muestra cuando se inicia la aplicación. Mostrará una lista de personas y el usuario podrá seleccionar en esa lista la persona cuyo informe de gastos desee mostrar.

  2. Abra ExpenseItHome.xaml.

  3. Establezca Title en "ExpenseIt - Home".

    Su XAML se debería parecer a lo siguiente en Visual Basic:

    <Page x:Class="ExpenseItHome"
      xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="https://schemas.microsoft.com/expression/blend/2008" 
      mc:Ignorable="d" 
      d:DesignHeight="300" d:DesignWidth="300"
      Title="ExpenseIt - Home">
        <Grid>
    
        </Grid>
    </Page>
    

    O a esto en C#:

    <Page x:Class="ExpenseIt.ExpenseItHome"
          xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
          xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006" 
          xmlns:d="https://schemas.microsoft.com/expression/blend/2008" 
          mc:Ignorable="d" 
          d:DesignHeight="300" d:DesignWidth="300"
        Title="ExpenseIt - Home">
    
        <Grid>
    
        </Grid>
    </Page>
    
  4. Abra MainWindow.xaml.

  5. Establezca la propiedad Source de NavigationWindow en "ExpenseItHome.xaml".

    Esto establece ExpenseItHome.xaml como la primera página que se abre cuando se inicia la aplicación. Su XAML se debería parecer a lo siguiente en Visual Basic:

    <NavigationWindow x:Class="MainWindow"
        xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
        Title="ExpenseIt" Height="350" Width="500" Source="ExpenseItHome.xaml">
    
    </NavigationWindow>
    

    O a esto en C#:

    <NavigationWindow x:Class="ExpenseIt.MainWindow"
        xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
        Title="ExpenseIt" Height="350" Width="500" Source="ExpenseItHome.xaml">
    
    </NavigationWindow>
    
  6. Agregue una nueva página (WPF) al proyecto denominada ExpenseReportPage.xaml.

    Esta página mostrará el informe de gastos de la persona que esté seleccionada en ExpenseItHome.xaml.

  7. Abra ExpenseReportPage.xaml.

  8. Establezca Title en "ExpenseIt - View Expense".

    Su XAML se debería parecer a lo siguiente en Visual Basic:

    <Page x:Class="ExpenseReportPage"
          xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
          xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006" 
          xmlns:d="https://schemas.microsoft.com/expression/blend/2008" 
          mc:Ignorable="d" 
          d:DesignHeight="300" d:DesignWidth="300"
          Title="ExpenseIt - View Expense">
        <Grid>
    
        </Grid>
    </Page>
    

    O a esto en C#:

    <Page x:Class="ExpenseIt.ExpenseReportPage"
          xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
          xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006" 
          xmlns:d="https://schemas.microsoft.com/expression/blend/2008" 
          mc:Ignorable="d" 
          d:DesignHeight="300" d:DesignWidth="300"
        Title="ExpenseIt - View Expense">
    
        <Grid>
    
        </Grid>
    </Page>
    
  9. Abra ExpenseItHome.xaml.vb y ExpenseReportPage.xaml.vb o ExpenseItHome.xaml.cs y ExpenseReportPage.xaml.cs.

    Al crear un nuevo archivo de paginación, Visual Studio crea automáticamente un código subyacente. Estos archivos de código subyacente controlan la lógica para responder a los datos proporcionados por el usuario.

    El código debe ser similar al que se muestra a continuación.

    Class ExpenseItHome
    
    End Class
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    
    namespace ExpenseIt
    {
        /// <summary>
        /// Interaction logic for ExpenseItHome.xaml
        /// </summary>
        public partial class ExpenseItHome : Page
        {
            public ExpenseItHome()
            {
                InitializeComponent();
            }
        }
    }
    
    Class ExpenseReportPage
    
    End Class
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    
    namespace ExpenseIt
    {
        /// <summary>
        /// Interaction logic for ExpenseReportPage.xaml
        /// </summary>
        public partial class ExpenseReportPage : Page
        {
            public ExpenseReportPage()
            {
                InitializeComponent();
            }
        }
    }
    
  10. Agregue una imagen denominada watermark.png al proyecto. Puede crear su propia imagen o copiar el archivo del código de ejemplo. Para obtener más información, vea Cómo: Agregar elementos existentes a un proyecto.

Compilar y ejecutar la aplicación

En esta sección, se compila y ejecuta la aplicación.

  1. Compile y ejecute la aplicación presionando F5 o seleccione Iniciar depuración en el menú Debug.

    La siguiente ilustración muestra la aplicación con los botones NavigationWindow.

    Captura de pantalla de ejemplo ExpenseIt

  2. Cierre la aplicación para volver a Visual Studio.

Crear el diseño

El diseño proporciona un modo ordenado de colocar los elementos de la UI, y también controla el tamaño y la posición de los mismos cuando la UI cambia de tamaño. Normalmente se crea un diseño con uno de los controles de diseño siguientes:

Cada uno de estos controles de diseño admite un tipo de diseño especial para sus elementos secundarios. Es posible cambiar de tamaño las páginas de ExpenseIt, y cada página tiene elementos organizados horizontal y verticalmente junto con otros elementos. Por lo tanto, Grid es el elemento de diseño ideal para la aplicación.

NotaNota

Para obtener más información sobre los elementos Panel, vea Información general sobre elementos Panel.Para obtener más información sobre diseño, vea Sistema de diseño.

En la sección, cree una tabla con una columna única con tres filas y un margen de 10 píxeles agregando definiciones de columna y de fila a la Grid de ExpenseItHome.xaml.

  1. Abra ExpenseItHome.xaml.

  2. Establezca la propiedad Margin en el elemento Grid en "10,0,10,10", que corresponde a los márgenes izquierdo, superior, derecho e inferior.

  3. Agregue el siguiente XAML entre las etiquetas Grid para crear las definiciones de columna y fila. 

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

    El Height de dos filas está establecido en Auto, lo que quiere decir que las filas se dimensionarán según su contenido. El Height predeterminado es Star, que significa que la fila será una proporción ponderada del espacio disponible. Por ejemplo si cada una de dos filas tiene un alto de "*", ambas tendrán un alto que es la mitad del espacio disponible.

    Su Grid debe tener la apariencia siguiente:

    <Grid Margin="10,0,10,10">
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition />
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
    </Grid>
    

Agregar controles

En esta sección, se actualiza la UI de la página principal para mostrar una lista de personas y los usuarios pueden seleccionar el nombre de la persona cuyo informe de gastos desean ver. Los controles son objetos de interfaz de usuario que permiten a los usuarios interactuar con una aplicación. Para obtener más información, vea Controles.

Para crear esta UI, se han agregado los elementos siguientes a ExpenseItHome.xaml:

  • Un control ListBox (para la lista de personas).

  • Un control Label (para el encabezado de la lista).

  • Un control Button (para hacer clic con objeto de ver el informe de gastos de la persona que está seleccionada en la lista).

Cada control se coloca en una fila de la Grid estableciendo la propiedad adjunta Grid.Row. Para obtener más información sobre propiedades adjuntas, vea Información general sobre propiedades asociadas.

  1. Abra ExpenseItHome.xaml.

  2. Agregue el código XAML siguiente entre las etiquetas Grid.

    
      <!-- People list -->
      <Border Grid.Column="0" Grid.Row="0" Height="35" Padding="5" Background="#4E87D4">
          <Label VerticalAlignment="Center" Foreground="White">Names</Label>
      </Border>
      <ListBox Name="peopleListBox" Grid.Column="0" Grid.Row="1">
          <ListBoxItem>Mike</ListBoxItem>
          <ListBoxItem>Lisa</ListBoxItem>
          <ListBoxItem>John</ListBoxItem>
          <ListBoxItem>Mary</ListBoxItem>
      </ListBox>
    
      <!-- View report button -->
      <Button Grid.Column="0" Grid.Row="2" Margin="0,10,0,0" Width="125"
    Height="25" HorizontalAlignment="Right">View</Button>
    
  3. Genere y ejecute la aplicación.

La siguiente ilustración muestra los controles que crea el XAML en esta sección.

Captura de pantalla de ejemplo ExpenseIt

Agregar una imagen y un título

En esta sección, la UI de la página principal se actualiza con una imagen y un título de página.

  1. Abra ExpenseItHome.xaml.

  2. Agregue otra columna a ColumnDefinitions con un Width fijo de 230 píxeles.

    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="230" />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    
  3. Agregue otra fila a RowDefinitions.

    <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition Height="Auto"/>
        <RowDefinition />
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    
  4. Mueva los controles a la segunda columna estableciendo Grid.Column en 1. Baje cada control una fila aumentando Grid.Row en 1.

      <Border Grid.Column="1" Grid.Row="1" Height="35" Padding="5" Background="#4E87D4">
          <Label VerticalAlignment="Center" Foreground="White">Names</Label>
      </Border>
      <ListBox Name="peopleListBox" Grid.Column="1" Grid.Row="2">
          <ListBoxItem>Mike</ListBoxItem>
          <ListBoxItem>Lisa</ListBoxItem>
          <ListBoxItem>John</ListBoxItem>
          <ListBoxItem>Mary</ListBoxItem>
      </ListBox>
    
      <!-- View report button -->
      <Button Grid.Column="1" Grid.Row="3" Margin="0,10,0,0" Width="125"
    Height="25" HorizontalAlignment="Right">View</Button>
    
  5. Establezca Background de Grid para que sea el archivo de imagen watermark.png.

    <Grid.Background>
        <ImageBrush ImageSource="watermark.png"/>
    </Grid.Background>
    
  6. Antes de Border, agregue Label con el contenido "View Expense Report" para que sea el título de la página.

    <Label Grid.Column="1" VerticalAlignment="Center" FontFamily="Trebuchet MS" 
            FontWeight="Bold" FontSize="18" Foreground="#0066cc">
        View Expense Report
    </Label>
    
  7. Genere y ejecute la aplicación.

En la ilustración siguiente se muestra el resultado de esta sección.

Captura de pantalla de ejemplo ExpenseIt

Agregar código para controlar eventos

  1. Abra ExpenseItHome.xaml.

  2. Agregue el controlador de eventos Click al elemento Button. Para obtener más información, vea Cómo: Crear controladores de eventos simples.

      <!-- View report button -->
      <Button Grid.Column="1" Grid.Row="3" Margin="0,10,0,0" Width="125"
    Height="25" HorizontalAlignment="Right" Click="Button_Click">View</Button>
    
  3. Abra ExpenseItHome.xaml.vb o ExpenseItHome.xaml.cs.

  4. Agregue el siguiente código al controlador de eventos Click, que hace que la ventana navegue hasta el archivo ExpenseReportPage.xaml.

            Private Sub Button_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
                ' View Expense Report
                Dim expenseReportPage As New ExpenseReportPage()
                Me.NavigationService.Navigate(expenseReportPage)
    
            End Sub
    
    private void Button_Click(object sender, RoutedEventArgs e)
    {
        // View Expense Report
        ExpenseReportPage expenseReportPage = new ExpenseReportPage();
        this.NavigationService.Navigate(expenseReportPage);
    
    }
    

Crear la interfaz de usuario para ExpenseReportPage

ExpenseReportPage.xaml muestra el informe de gastos de la persona que se seleccionó en ExpenseItHome.xaml. En esta sección se agregan los controles y se crea la UI para ExpenseReportPage.xaml. También se agrega un fondo y colores de relleno a los distintos elementos de la UI.

  1. Abra ExpenseReportPage.xaml.

  2. Agregue el código XAML siguiente entre las etiquetas Grid.

    Esta interfaz de usuario es similar a la interfaz de usuario creada en ExpenseItHome.xaml, con la salvedad de que los datos del informe se muestran en DataGrid.

    <Grid.Background>
        <ImageBrush ImageSource="watermark.png" />
    </Grid.Background>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="230" />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition />
    </Grid.RowDefinitions>
    
    
    <Label Grid.Column="1" VerticalAlignment="Center" FontFamily="Trebuchet MS" 
    FontWeight="Bold" FontSize="18" Foreground="#0066cc">
        Expense Report For:
    </Label>
    <Grid Margin="10" Grid.Column="1" Grid.Row="1">
    
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition />
        </Grid.RowDefinitions>
    
        <!-- Name -->
        <StackPanel Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="0" Orientation="Horizontal">
            <Label Margin="0,0,0,5" FontWeight="Bold">Name:</Label>
            <Label Margin="0,0,0,5" FontWeight="Bold"></Label>
        </StackPanel>
    
        <!-- Department -->
        <StackPanel Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="1" Orientation="Horizontal">
            <Label Margin="0,0,0,5" FontWeight="Bold">Department:</Label>
            <Label Margin="0,0,0,5" FontWeight="Bold"></Label>
        </StackPanel>
    
        <Grid Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="2" VerticalAlignment="Top" 
              HorizontalAlignment="Left">
            <!-- Expense type and Amount table -->
            <DataGrid  AutoGenerateColumns="False" RowHeaderWidth="0" >
                <DataGrid.ColumnHeaderStyle>
                    <Style TargetType="{x:Type DataGridColumnHeader}">
                        <Setter Property="Height" Value="35" />
                        <Setter Property="Padding" Value="5" />
                        <Setter Property="Background" Value="#4E87D4" />
                        <Setter Property="Foreground" Value="White" />
                    </Style>
                </DataGrid.ColumnHeaderStyle>
                <DataGrid.Columns>
                    <DataGridTextColumn Header="ExpenseType" />
                    <DataGridTextColumn Header="Amount"  />
                </DataGrid.Columns>
            </DataGrid>
        </Grid>
    </Grid>
    
  3. Genere y ejecute la aplicación.

    NotaNota

    Si obtiene un error que indica que DataGrid no se encuentra o no existe, asegúrese de que el proyecto tiene como destino .NET Framework 4.Para obtener más información, vea Cómo: Elegir perfil o versión de destino de .NET Framework.

  4. Haga clic en el botón Ver.

    Aparecerá la página de informe de gastos.

La ilustración siguiente muestra los elementos de la UI agregados a ExpenseReportPage.xaml. Observe que el botón de navegación hacia atrás está habilitado.

Captura de pantalla de ejemplo ExpenseIt

Estilo de los controles

Es habitual que todos los elementos del mismo tipo de una UI presenten la misma apariencia. UI utiliza estilos para permitir la reutilización de las distintas apariencias en diversos elementos. Esta posibilidad de reutilizar los estilos ayuda a simplificar la creación y la administración de XAML. Para obtener más información acerca de los estilos, consulte Aplicar estilos y plantillas. En esta sección se reemplazan por estilos los atributos que se definieron en pasos anteriores para los distintos elementos.

  1. Abra Application.xaml o App.xaml.

  2. Agregue el código XAML siguiente entre las etiquetas Application.Resources:

    
    <!-- Header text style -->
    <Style x:Key="headerTextStyle">
        <Setter Property="Label.VerticalAlignment" Value="Center"></Setter>
        <Setter Property="Label.FontFamily" Value="Trebuchet MS"></Setter>
        <Setter Property="Label.FontWeight" Value="Bold"></Setter>
        <Setter Property="Label.FontSize" Value="18"></Setter>
        <Setter Property="Label.Foreground" Value="#0066cc"></Setter>
    </Style>
    
    <!-- Label style -->
    <Style x:Key="labelStyle" TargetType="{x:Type Label}">
        <Setter Property="VerticalAlignment" Value="Top" />
        <Setter Property="HorizontalAlignment" Value="Left" />
        <Setter Property="FontWeight" Value="Bold" />
        <Setter Property="Margin" Value="0,0,0,5" />
    </Style>
    
    <!-- DataGrid header style -->
    <Style x:Key="columnHeaderStyle" TargetType="{x:Type DataGridColumnHeader}">
        <Setter Property="Height" Value="35" />
        <Setter Property="Padding" Value="5" />
        <Setter Property="Background" Value="#4E87D4" />
        <Setter Property="Foreground" Value="White" />
    </Style>
    
    <!-- List header style -->
    <Style x:Key="listHeaderStyle" TargetType="{x:Type Border}">
        <Setter Property="Height" Value="35" />
        <Setter Property="Padding" Value="5" />
        <Setter Property="Background" Value="#4E87D4" />
    </Style>
    
    <!-- List header text style -->
    <Style x:Key="listHeaderTextStyle" TargetType="{x:Type Label}">
        <Setter Property="Foreground" Value="White" />
        <Setter Property="VerticalAlignment" Value="Center" />
        <Setter Property="HorizontalAlignment" Value="Left" />
    </Style>
    
    <!-- Button style -->
    <Style x:Key="buttonStyle" TargetType="{x:Type Button}">
        <Setter Property="Width" Value="125" />
        <Setter Property="Height" Value="25" />
        <Setter Property="Margin" Value="0,10,0,0" />
        <Setter Property="HorizontalAlignment" Value="Right" />
    </Style>
    

    Este XAML agrega los estilos siguientes:

    • headerTextStyle: para dar formato al control Label de título de página.

    • labelStyle: para dar formato a los controles Label.

    • columnHeaderStyle: para dar formato a DataGridColumnHeader.

    • listHeaderStyle: para dar formato a los controles Border de encabezado de lista.

    • listHeaderTextStyle: para dar formato a los controles Label de encabezado de lista.

    • buttonStyle: para dar formato a Button en "ExpenseItHome.xaml".

    Observe que los estilos son recursos y elementos secundarios del elemento de propiedad Application.Resources. En esta ubicación, los estilos se aplican a todos los elementos de una aplicación. Para obtener un ejemplo del uso de los recursos en una aplicación de .NET Framework, consulte Cómo: Usar recursos de aplicaciones.

  3. Abra ExpenseItHome.xaml.

  4. Reemplace todo lo que hay entre los elementos Grid por el siguiente XAML.

    <Grid.Background>
        <ImageBrush ImageSource="watermark.png"  />
    </Grid.Background>
    
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="230" />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    
    <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition Height="Auto"/>
        <RowDefinition />
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    
    <!-- People list -->
    
    <Label Grid.Column="1" Style="{StaticResource headerTextStyle}" >
        View Expense Report
    </Label>
    
    <Border Grid.Column="1" Grid.Row="1" Style="{StaticResource listHeaderStyle}">
        <Label Style="{StaticResource listHeaderTextStyle}">Names</Label>
    </Border>
    <ListBox Name="peopleListBox" Grid.Column="1" Grid.Row="2">
        <ListBoxItem>Mike</ListBoxItem>
        <ListBoxItem>Lisa</ListBoxItem>
        <ListBoxItem>John</ListBoxItem>
        <ListBoxItem>Mary</ListBoxItem>
    </ListBox>
    
    <!-- View report button -->
    <Button Grid.Column="1" Grid.Row="3" Click="Button_Click" Style="{StaticResource buttonStyle}">View</Button>
    

    Las propiedades como VerticalAlignment y FontFamily que definen la apariencia de cada control se quitan y reemplazan aplicando los estilos. Por ejemplo headerTextStyle se aplica a Label "View Expense Report".

  5. Abra ExpenseReportPage.xaml.

  6. Reemplace todo lo que hay entre los elementos Grid por el siguiente XAML.

    <Grid.Background>
        <ImageBrush ImageSource="watermark.png" />
    </Grid.Background>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="230" />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition />
    </Grid.RowDefinitions>
    
    
    <Label Grid.Column="1" Style="{StaticResource headerTextStyle}">
        Expense Report For:
    </Label>
    <Grid Margin="10" Grid.Column="1" Grid.Row="1">
    
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition />
        </Grid.RowDefinitions>
    
        <!-- Name -->
        <StackPanel Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="0" Orientation="Horizontal">
            <Label Style="{StaticResource labelStyle}">Name:</Label>
            <Label Style="{StaticResource labelStyle}"></Label>
        </StackPanel>
    
        <!-- Department -->
        <StackPanel Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="1" 
    Orientation="Horizontal">
            <Label Style="{StaticResource labelStyle}">Department:</Label>
            <Label Style="{StaticResource labelStyle}"></Label>
        </StackPanel>
    
        <Grid Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="2" VerticalAlignment="Top" 
              HorizontalAlignment="Left">
            <!-- Expense type and Amount table -->
            <DataGrid ColumnHeaderStyle="{StaticResource columnHeaderStyle}" 
                      AutoGenerateColumns="False" RowHeaderWidth="0" >
                <DataGrid.Columns>
                    <DataGridTextColumn Header="ExpenseType" />
                    <DataGridTextColumn Header="Amount"  />
                </DataGrid.Columns>
            </DataGrid>
        </Grid>
    </Grid>
    

    Esto agrega estilos a los elementos Border y Label.

  7. Genere y ejecute la aplicación.

    Después de agregar el marcado XAML de esta sección, la aplicación presenta la misma apariencia que tenía antes de actualizarla con los estilos.

Enlazar datos a controles

En esta sección se crean los datos XML que se enlazan a varios controles.

  1. Abra ExpenseItHome.xaml.

  2. Después del elemento inicial Grid, agregue el siguiente XAML para crear un XmlDataProvider que contenga los datos de cada persona.

    Los datos se crean como un recurso Grid. Normalmente esto se cargaría como un archivo, pero por sencillez los datos se agregan alineados.

    <Grid.Resources>
    
    
    ...
    
    
    <!-- Expense Report Data -->
    <XmlDataProvider x:Key="ExpenseDataSource" XPath="Expenses">
        <x:XData>
            <Expenses >
                <Person Name="Mike" Department="Legal">
                    <Expense ExpenseType="Lunch" ExpenseAmount="50" />
                    <Expense ExpenseType="Transportation" ExpenseAmount="50" />
                </Person>
                <Person Name="Lisa" Department="Marketing">
                    <Expense ExpenseType="Document printing"
          ExpenseAmount="50"/>
                    <Expense ExpenseType="Gift" ExpenseAmount="125" />
                </Person>
                <Person Name="John" Department="Engineering">
                    <Expense ExpenseType="Magazine subscription" 
         ExpenseAmount="50"/>
                    <Expense ExpenseType="New machine" ExpenseAmount="600" />
                    <Expense ExpenseType="Software" ExpenseAmount="500" />
                </Person>
                <Person Name="Mary" Department="Finance">
                    <Expense ExpenseType="Dinner" ExpenseAmount="100" />
                </Person>
            </Expenses>
        </x:XData>
    </XmlDataProvider>
    
    
    ...
    
    
    </Grid.Resources>
    
  3. En el recurso Grid, agregue la siguiente DataTemplate, que define cómo mostrar los datos en ListBox. Para obtener más información sobre plantillas de datos, vea Información general sobre plantillas de datos.

    <Grid.Resources>
    
    
    ...
    
    
    <!-- Name item template -->
    <DataTemplate x:Key="nameItemTemplate">
        <Label Content="{Binding XPath=@Name}"/>
    </DataTemplate>
    
    
    ...
    
    
    </Grid.Resources>
    
  4. Reemplace ListBox por el siguiente XAML.

    <ListBox Name="peopleListBox" Grid.Column="1" Grid.Row="2" 
             ItemsSource="{Binding Source={StaticResource ExpenseDataSource}, XPath=Person}"
             ItemTemplate="{StaticResource nameItemTemplate}">
    </ListBox>
    

    Este XAML enlaza la propiedad ItemsSource de ListBox al origen de datos y aplica la plantilla de datos como ItemTemplate.

Conectar los datos a los controles

En esta sección, escribirá el código que recupera el elemento actual que está seleccionado en la lista de personas de la página ExpenseItHome.xaml y que pasa su referencia al constructor de ExpenseReportPage durante la creación de instancias. ExpenseReportPage establece su contexto de datos con el elemento que se pasa, que es el elemento con el que se enlazarán los controles definidos en ExpenseReportPage.xaml.

  1. Abra ExpenseReportPage.xaml.vb o ExpenseReportPage.xaml.cs.

  2. Agregue un constructor que tome un objeto de modo que pueda pasar los datos del informe de gastos de la persona seleccionada.

        Partial Public Class ExpenseReportPage
            Inherits Page
            Public Sub New()
                InitializeComponent()
            End Sub
    
            ' Custom constructor to pass expense report data
            Public Sub New(ByVal data As Object)
                Me.New()
                ' Bind to expense report data.
                Me.DataContext = data
            End Sub
    
        End Class
    
    public partial class ExpenseReportPage : Page
    {
        public ExpenseReportPage()
        {
            InitializeComponent();
        }
    
        // Custom constructor to pass expense report data
        public ExpenseReportPage(object data):this()
        {
            // Bind to expense report data.
            this.DataContext = data;
        }
    
    }
    
  3. Abra ExpenseItHome.xaml.vb o ExpenseItHome.xaml.cs.

  4. Cambie el controlador de eventos Click para llamar al nuevo constructor que pasa los datos del informe de gastos de la persona seleccionada.

            Private Sub Button_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
                ' View Expense Report
                Dim expenseReportPage As New ExpenseReportPage(Me.peopleListBox.SelectedItem)
                Me.NavigationService.Navigate(expenseReportPage)
    
            End Sub
    
    private void Button_Click(object sender, RoutedEventArgs e)
    {
        // View Expense Report
        ExpenseReportPage expenseReportPage = new ExpenseReportPage(this.peopleListBox.SelectedItem);
        this.NavigationService.Navigate(expenseReportPage);
    
    }
    

Dar estilos a los datos con plantillas de datos

En esta sección, actualizará la UI para cada elemento de las listas enlazadas a datos utilizando las plantillas de datos.

  1. Abra ExpenseReportPage.xaml.

  2. Enlace el contenido de elementos Label "Department" y "Name" a la propiedad de origen de datos adecuada. Para obtener más información sobre el enlace de datos, vea Información general sobre el enlace de datos.

    <!-- Name -->
    <StackPanel Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="0" Orientation="Horizontal">
        <Label Style="{StaticResource labelStyle}">Name:</Label>
        <Label Style="{StaticResource labelStyle}" Content="{Binding XPath=@Name}"></Label>
    </StackPanel>
    
    <!-- Department -->
    <StackPanel Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="1" Orientation="Horizontal">
        <Label Style="{StaticResource labelStyle}">Department:</Label>
        <Label Style="{StaticResource labelStyle}" Content="{Binding XPath=@Department}"></Label>
    </StackPanel>
    
  3. Después de abrir el elemento Grid, agregue las siguientes plantillas de datos, que definen cómo mostrar los datos del informe de gastos.

    <!--Templates to display expense report data-->
    <Grid.Resources>
        <!-- Reason item template -->
        <DataTemplate x:Key="typeItemTemplate">
            <Label Content="{Binding XPath=@ExpenseType}"/>
        </DataTemplate>
        <!-- Amount item template -->
        <DataTemplate x:Key="amountItemTemplate">
            <Label Content="{Binding XPath=@ExpenseAmount}"/>
        </DataTemplate>
    </Grid.Resources>
    
  4. Aplique las plantillas a las columnas de DataGrid que muestran los datos del informe de gastos.

    <!-- Expense type and Amount table -->
    <DataGrid ItemsSource="{Binding XPath=Expense}" ColumnHeaderStyle="{StaticResource columnHeaderStyle}" AutoGenerateColumns="False" RowHeaderWidth="0" >
    
        <DataGrid.Columns>
            <DataGridTextColumn Header="ExpenseType" Binding="{Binding XPath=@ExpenseType}"  />
            <DataGridTextColumn Header="Amount" Binding="{Binding XPath=@ExpenseAmount}" />
        </DataGrid.Columns>
    
    </DataGrid>
    
  5. Genere y ejecute la aplicación.

  6. Seleccione una persona y haga clic en el botón Ver.

En la siguiente ilustración se muestran las dos páginas de la aplicación ExpenseIt con los controles, el diseño, los estilos, el enlace de datos y las plantillas de datos aplicados.

Capturas de pantalla de ejemplo ExpenseIt

Procedimientos recomendados

En este ejemplo se muestra una característica específica de WPF y, por consiguiente, no sigue las recomendaciones de desarrollo de aplicaciones. Para obtener información completa sobre los procedimientos recomendados de desarrollo de aplicaciones de WPF y .NET Framework, consulte los temas siguientes según corresponda:

Pasos adicionales

Ahora tiene a su disposición varias técnicas para crear una UI mediante Windows Presentation Foundation (WPF). Ya debería tener una idea general de los bloques de creación necesarios para la creación de una aplicación .NET Framework enlazada a datos. Este tema no pretende ser exhaustivo, pero se supone que ahora ya conoce algunas de las posibilidades que puede descubrir por sí mismo además de las técnicas que se tratan en este tema.

Para obtener más información sobre la arquitectura y los modelos de programación WPF, consulte los siguientes temas:

Para obtener información sobre la creación de aplicaciones, vea los siguientes temas:

Vea también

Conceptos

Información general sobre elementos Panel

Información general sobre plantillas de datos

Compilar una aplicación de WPF (WPF)

Otros recursos

Estilos y plantillas

Historial de cambios

Fecha

Historial

Motivo

Diciembre de 2010

Se han agregado notas sobre el uso de .NET Framework 4 como destino.

Mejora de la información.