Tutorial: Creación de la primera aplicación WPF en Visual Studio 2019

En este artículo se muestra cómo desarrollar una aplicación de escritorio de Windows Presentation Foundation (WPF) que incluye los elementos comunes a la mayoría de las aplicaciones WPF: marcado de lenguaje XAML (XAML), código subyacente, definiciones de aplicación, controles, diseño, enlace de datos y estilos. Para desarrollar la aplicación, usará Visual Studio.

Importante

Este artículo se ha escrito para .NET Framework. Para empezar a trabajar con .NET 5 o .NET 6, consulte Tutorial: Creación de una nueva aplicación WPF (WPF .NET).

En este tutorial aprenderá a:

  • Cree un proyecto de WPF.
  • Use XAML para diseñar la apariencia de la interfaz de usuario (UI) de la aplicación.
  • Escribir código para compilar el comportamiento de la aplicación.
  • Cree una definición de aplicación para administrar la aplicación.
  • Agregue controles y cree el diseño para crear la interfaz de usuario de la aplicación.
  • Cree estilos para una apariencia coherente en toda la interfaz de usuario de la aplicación.
  • Enlace la interfaz de usuario a datos, tanto para rellenar la interfaz de usuario a partir de los datos como para mantener los datos y la interfaz de usuario sincronizados.

Al final del tutorial, habrá creado una aplicación independiente de Windows que permite a los usuarios ver informes de gastos de personas seleccionadas. La aplicación se compone de varias páginas de WPF que se hospedan en una ventana de estilo explorador.

Sugerencia

El código de ejemplo que se usa en este tutorial está disponible para Visual Basic y C# en Tutorial WPF App Sample Code.

Puede alternar el lenguaje de código del código de ejemplo entre C# y Visual Basic mediante el selector de idioma de la parte superior de esta página.

Prerrequisitos

Creación del proyecto de aplicación

El primer paso consiste en crear la infraestructura de la aplicación, que incluye una definición de aplicación, dos páginas y una imagen.

  1. Cree un proyecto de aplicación WPF en Visual Basic o Visual C# denominado ExpenseIt :

    1. Abra Visual Studio y seleccione Crear un nuevo proyecto en el menú Introducción.

      Se abre el cuadro de diálogo Crear un nuevo proyecto.

    2. En la lista desplegable Lenguaje, seleccione C# o Visual Basic.

    3. Seleccione la plantilla Aplicación WPF (.NET Framework) y, a continuación, seleccione Siguiente.

      Cuadro de diálogo Crear un proyecto

      Se abre el cuadro de diálogo Configurar el nuevo proyecto.

    4. Escriba el nombre del ExpenseIt proyecto y, a continuación, seleccione Crear.

      Cuadro de diálogo Configurar un nuevo proyecto

      Visual Studio crea el proyecto y abre el diseñador para la ventana de aplicación predeterminada denominada MainWindow.xaml.

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

    Este archivo XAML define una aplicación WPF y cualquier recurso de aplicación. También se usa este archivo para especificar la interfaz de usuario, en este caso MainWindow.xaml, que se muestra automáticamente cuando se inicia la aplicación.

    El CÓDIGO XAML debe tener un aspecto parecido al siguiente en Visual Basic:

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

    Y como se muestra a continuación en C#:

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

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

  4. Cambie el Window elemento a , como se muestra en el código XAML NavigationWindow siguiente:

    <NavigationWindow x:Class="ExpenseIt.MainWindow"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         ...
    </NavigationWindow>
    

    Esta aplicación navega a contenido diferente en función de la entrada del usuario. Este es el motivo por Window el que el principal debe cambiarse a NavigationWindow . NavigationWindow hereda todas las propiedades de Window . El NavigationWindow elemento del archivo XAML crea una instancia de la clase NavigationWindow . Para obtener más información, vea Información general de navegación.

  5. Quite los Grid elementos de entre las NavigationWindow etiquetas.

  6. Cambie las siguientes propiedades en el código XAML para el NavigationWindow elemento :

    • Establezca la Title propiedad en " ExpenseIt ".

    • Establezca la Height propiedad en 350 píxeles.

    • Establezca la Width propiedad en 500 píxeles.

    El código XAML debe tener un aspecto parecido al siguiente para Visual Basic:

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

    Y como se muestra a continuación para C#:

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

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

  8. Si usa C#, cambie la MainWindow clase para derivar de NavigationWindow . (En Visual Basic, esto sucede automáticamente cuando se cambia la ventana en XAML). El código de C# debería tener ahora el siguiente aspecto:

    
    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 al proyecto y así mismo denle el nombre ExpenseItHome.xaml :

    1. En Explorador de soluciones, haga clic con el botón derecho en el nodo ExpenseIt del proyecto y elija Agregar > página.

    2. En el cuadro de diálogo Agregar nuevo elemento, la plantilla Página (WPF) ya está seleccionada. Escriba el nombre ExpenseItHome y, a continuación, seleccione Agregar.

    Esta página es la primera que se muestra cuando se inicia la aplicación. Se mostrará una lista de personas entre las que seleccionar, para mostrar un informe de gastos.

  2. Abra ExpenseItHome.xaml.

  3. Establezca en Title " ExpenseIt - Home ".

  4. Establezca en DesignHeight 350 píxeles y DesignWidth en 500 píxeles.

    El código XAML aparece ahora como se muestra a continuación para Visual Basic:

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

    Y como se muestra a continuación para C#:

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

  6. Agregue una Source propiedad al elemento y esta establezca en " NavigationWindow ExpenseItHome.xaml ".

    Esto establece ExpenseItHome.xaml para que sea la primera página que se abre cuando se inicia la aplicación.

    Xaml de ejemplo en Visual Basic:

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

    Y en C#:

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

    Sugerencia

    También puede establecer la propiedad Origen en la categoría Varios de la ventana Propiedades.

    Propiedad Source en ventana Propiedades

  7. Agregue otra nueva página de WPF al proyecto y asípórmela ExpenseReportPage.xaml::

    1. En Explorador de soluciones, haga clic con el botón derecho en el nodo ExpenseIt del proyecto y elija Agregar > página.

    2. En el cuadro de diálogo Agregar nuevo elemento, seleccione la plantilla Página (WPF). Escriba el nombre ExpenseReportPage y, a continuación, seleccione Agregar.

    En esta página se mostrará el informe de gastos de la persona seleccionada en la ExpenseItHome página.

  8. Abra ExpenseReportPage.xaml.

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

  10. Establezca en DesignHeight 350 píxeles y DesignWidth en 500 píxeles.

    ExpenseReportPage.xaml ahora tiene un aspecto similar al siguiente en Visual Basic:

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

    Y como se muestra a continuación en C#:

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

    Al crear un nuevo archivo page, Visual Studio automáticamente su archivo de código subyacente. Estos archivos de código subyacente controlan la lógica para responder a la entrada del usuario.

    El código debe tener un aspecto parecido al siguiente para ExpenseItHome :

    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 ExpenseItHome
    
    End Class
    

    Y como se muestra a continuación para ExpenseReportPage:

    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();
            }
        }
    }
    
    Class ExpenseReportPage
    
    End Class
    
  12. Agregue una imagen denominada watermark.png al proyecto. Puede crear su propia imagen, copiar el archivo del código de ejemplo u obtenerlo del repositorio microsoft/WPF-Samples GitHub.

    1. Haga clic con el botón derecho en el nodo del proyecto y seleccione Agregar > elemento existente o presione Mayús + Alt + A.

    2. En el cuadro de diálogo Agregar elemento existente, establezca el filtro de archivos en Todos los archivos o Archivos de imagen, busque el archivo de imagen que desea usar y, a continuación, seleccione Agregar.

Compilación y ejecución de la aplicación

  1. Para compilar y ejecutar la aplicación, presione F5 o seleccione Iniciar depuración en el menú Depurar.

    En la ilustración siguiente se muestra la aplicación con los NavigationWindow botones:

    Aplicación después de compilarla y ejecutarla.

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

Creación del diseño

El diseño proporciona una manera ordenada de colocar elementos de la interfaz de usuario y también administra el tamaño y la posición de esos elementos cuando se cambia el tamaño de una interfaz de usuario. Normalmente, se crea un diseño con uno de los controles de diseño siguientes:

  • Canvas : define un área en la que puede colocar explícitamente los elementos secundarios mediante coordenadas relativas al área canvas.
  • DockPanel : define un área donde puede organizar los elementos secundarios horizontal o verticalmente, en relación entre sí.
  • Grid : define un área de cuadrícula flexible que consta de columnas y filas.
  • StackPanel : organiza los elementos secundarios en una sola línea que se puede orientar horizontal o verticalmente.
  • VirtualizingStackPanel : organiza y virtualiza el contenido en una sola línea orientada horizontal o verticalmente.
  • WrapPanel : coloca los elementos secundarios en posición secuencial de izquierda a derecha, lo que separa el contenido de la siguiente línea en el borde del cuadro de contenido. El orden posterior se produce secuencialmente de arriba abajo o de derecha a izquierda, según el valor de la propiedad Orientation.

Cada uno de estos controles de diseño admite un tipo determinado de diseño para sus elementos secundarios. ExpenseIt se puede cambiar el tamaño de las páginas y cada página tiene elementos que se organizan horizontal y verticalmente junto con otros elementos. En este ejemplo, Grid se usa como elemento de diseño para la aplicación.

Sugerencia

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

En esta sección, creará una tabla de una sola columna con tres filas y un margen de 10 píxeles agregando definiciones de columna y fila a Grid en ExpenseItHome.xaml .

  1. En , establezca la propiedad del elemento en ExpenseItHome.xaml Margin Grid "10,0,10,10", que corresponde a los márgenes izquierdo, superior, derecho e inferior:

    <Grid Margin="10,0,10,10">
    

    Sugerencia

    También puede establecer los valores de Margen en la ventana Propiedades, en la categoría Diseño:

    Valores de margen en ventana Propiedades

  2. Agregue el siguiente CÓDIGO XAML entre las Grid etiquetas para crear las definiciones de fila y columna:

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

    El de dos filas se establece en , lo que significa que el tamaño de las filas se basa Height en el contenido de las Auto filas. El valor predeterminado es el ajuste de tamaño, lo que significa que el alto de fila es una proporción Height Star ponderada del espacio disponible. Por ejemplo, si dos filas tienen un de "*", cada una tiene una altura que es la Height mitad del espacio disponible.

    Ahora Grid debería contener el código XAML 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, actualizará la interfaz de usuario de la página principal para mostrar una lista de personas, donde seleccionará una persona para mostrar su informe de gastos. Los controles son objetos de interfaz de usuario que permiten a los usuarios interactuar con su aplicación. Para obtener más información, consulte Controles.

Para crear esta interfaz de usuario, agregará los siguientes elementos a ExpenseItHome.xaml :

  • (para ListBox la lista de personas).
  • (para Label el encabezado de lista).
  • (para hacer clic para ver el informe de gastos de Button la persona seleccionada en la lista).

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

  1. En ExpenseItHome.xaml , agregue el siguiente CÓDIGO XAML en algún lugar entre las Grid etiquetas:

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

    Sugerencia

    También puede crear los controles arrastrándolos desde la ventana Cuadro de herramientas a la ventana de diseño y, a continuación, estableciendo sus propiedades en la ventana Propiedades.

  2. Compile y ejecute la aplicación.

    En la ilustración siguiente se muestran los controles que ha creado:

Captura de pantalla de ejemplo expenseIt que muestra una lista de nombres

Adición de una imagen y un título

En esta sección, actualizará la interfaz de usuario de la página principal con una imagen y un título de página.

  1. En ExpenseItHome.xaml , agregue otra columna a con un valor fijo de ColumnDefinitions Width 230 píxeles:

    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="230" />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    
  2. Agregue otra fila a RowDefinitions , para un total de cuatro filas:

    <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition Height="Auto"/>
        <RowDefinition />
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    
  3. Mueva los controles a la segunda columna estableciendo la propiedad en 1 en cada uno de los tres controles Grid.Column (Border, ListBox y Button).

  4. Bajar cada control de una fila incrementando su valor en 1 para cada uno de los tres controles Grid.Row (Border, ListBox y Button) y para el elemento Border.

    El CÓDIGO XAML de los tres controles ahora es similar al siguiente:

      <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 la propiedad Background en el watermark.png de imagen mediante la adición del siguiente código XAML en cualquier lugar entre las <Grid> </Grid> etiquetas y :

    <Grid.Background>
        <ImageBrush ImageSource="watermark.png"/>
    </Grid.Background>
    
  6. Antes del Border elemento , agregue un con el contenido Label "Ver informe de gastos". Esta etiqueta es 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. Compile y ejecute la aplicación.

En la ilustración siguiente se muestran los resultados de lo que acaba de agregar:

Captura de pantalla de ejemplo expenseIt que muestra el nuevo fondo de la imagen y el título de la página

Adición de código para controlar eventos

  1. En ExpenseItHome.xaml , agregue un controlador de eventos al elemento Click Button . Para obtener más información, vea Cómo: Crear un controlador de eventos simple.

      <!-- 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>
    
  2. Abra ExpenseItHome.xaml.vb o ExpenseItHome.xaml.cs .

  3. Agregue el código siguiente a la clase ExpenseItHome para agregar un controlador de eventos de clic de botón. El controlador de eventos abre la página ExpenseReportPage.

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        // View Expense Report
        ExpenseReportPage expenseReportPage = new ExpenseReportPage();
        this.NavigationService.Navigate(expenseReportPage);
    }
    
    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
    

Creación de la interfaz de usuario para ExpenseReportPage

ExpenseReportPage.xaml muestra el informe de gastos de la persona seleccionada en la ExpenseItHome página. En esta sección, creará la interfaz de usuario de ExpenseReportPage. También agregará colores de fondo y relleno a los distintos elementos de la interfaz de usuario.

  1. Abra ExpenseReportPage.xaml.

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

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

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

  3. Compile y ejecute la aplicación.

  4. Seleccione el botón Ver.

    Se mostrará la página de informe de gastos Observe también que el botón de navegación Atrás está habilitado.

En la ilustración siguiente se muestran los elementos de la interfaz de usuario agregados a ExpenseReportPage.xaml.

Captura de pantalla de ejemplo expenseIt que muestra la interfaz de usuario que acaba de crear para ExpenseReportPage.

Controles de estilo

La apariencia de varios elementos suele ser la misma para todos los elementos del mismo tipo en una interfaz de usuario. La interfaz de usuario usa estilos para hacer que las apariencias se re reutilizables en varios elementos. La reusabilidad de los estilos ayuda a simplificar la creación y administración de XAML. En esta sección se reemplazan los atributos de cada elemento que se definieron en pasos anteriores por estilos.

  1. Abra Application.xaml o App.xaml.

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

    
    <!-- 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 código XAML agrega los estilos siguientes:

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

    • labelStyle: para dar formato a los controles Label .

    • columnHeaderStyle: para dar formato a DataGridColumnHeader.

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

    • listHeaderTextStyle: para dar formato al encabezado de lista Label .

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

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

  3. En ExpenseItHome.xaml , reemplace todo lo que hay entre los elementos por el código XAML Grid siguiente:

       <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, se headerTextStyle aplica a "Ver informe de gastos". Label

  4. Abra ExpenseReportPage.xaml.

  5. Reemplace todo el contenido Grid entre los elementos por el código XAML siguiente:

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

    Este XAML agrega estilos a los Label elementos Border y .

  6. Compile y ejecute la aplicación. La apariencia de la ventana es la misma que la anterior.

    Captura de pantalla de ejemplo expenseIt con la misma apariencia que en la última sección.

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

Enlazar datos a un control

En esta sección, creará los datos XML enlazados a varios controles.

  1. En , después del elemento de apertura, agregue el siguiente CÓDIGO XAML para crear un objeto ExpenseItHome.xaml que contenga los datos de cada Grid XmlDataProvider persona:

    <Grid.Resources>
        <!-- Expense Report Data -->
        <XmlDataProvider x:Key="ExpenseDataSource" XPath="Expenses">
            <x:XData>
                <Expenses xmlns="">
                    <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>
    

    Los datos se crean como Grid un recurso. Normalmente, estos datos se cargarían como un archivo, pero para simplificar los datos se agregan en línea.

  2. Dentro del elemento , agregue el siguiente elemento , que define cómo mostrar <Grid.Resources> los datos en , después del elemento <xref:System.Windows.DataTemplate> ListBox <XmlDataProvider> :

    <Grid.Resources>
        <!-- Name item template -->
        <DataTemplate x:Key="nameItemTemplate">
            <Label Content="{Binding XPath=@Name}"/>
        </DataTemplate>
    </Grid.Resources>
    

    Para obtener más información sobre las plantillas de datos, vea Introducción a las plantillas de datos.

  3. Reemplace el objeto ListBox existente por el código XAML siguiente:

    <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 de al origen de datos ItemsSource y aplica la plantilla de datos como ListBox ItemTemplate .

Conectar datos a controles

A continuación, agregará código para recuperar el nombre seleccionado en la página y pasarlo al ExpenseItHome constructor de ExpenseReportPage. ExpenseReportPage establece su contexto de datos con el elemento pasado, que es a lo que se enlazan los controles definidos en ExpenseReportPage.xaml.

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

  2. Agregue un constructor que acepte un objeto, para que pueda pasar los datos del informe de gastos de la persona seleccionada.

    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;
        }
    }
    
    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
    
  3. Abra ExpenseItHome.xaml.vb o ExpenseItHome.xaml.cs .

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

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        // View Expense Report
        ExpenseReportPage expenseReportPage = new ExpenseReportPage(this.peopleListBox.SelectedItem);
        this.NavigationService.Navigate(expenseReportPage);
    }
    
    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
    

Aplicación de estilo a los datos con plantillas de datos

En esta sección, actualizará la interfaz de usuario de cada elemento de las listas enlazadas a datos mediante plantillas de datos.

  1. Abra ExpenseReportPage.xaml.

  2. Enlace el contenido de los elementos "Name" y "Department" Label 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 del elemento Grid de apertura, 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. Reemplace los DataGridTextColumn elementos por DataGridTemplateColumn debajo del elemento y aplique las DataGrid plantillas a ellos. Además, especifique el ItemsSource atributo con su valor en el elemento DataGrid .

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

  6. Seleccione una persona y, a continuación, seleccione el botón Ver.

En la ilustración siguiente se muestran ambas páginas de la ExpenseIt aplicación con controles, diseño, estilos, enlace de datos y plantillas de datos aplicadas:

Ambas páginas de la aplicación muestran la lista de nombres y un informe de gastos.

Nota

En este ejemplo se muestra una característica específica de WPF y no se siguen todos los procedimientos recomendados para aspectos como la seguridad, la localización y la accesibilidad. Para obtener una cobertura completa de WPF y los procedimientos recomendados de desarrollo de aplicaciones .NET, consulte los temas siguientes:

Pasos siguientes

En este tutorial ha aprendido varias técnicas para crear una interfaz de usuario mediante Windows Presentation Foundation (WPF). Ahora debería tener un conocimiento básico de los bloques de creación de una aplicación .NET enlazada a datos. Para más información sobre los modelos de programación y arquitectura de WPF, vea los temas siguientes:

Para más información sobre la creación de aplicaciones, vea los temas siguientes:

Consulte también