Introducción a WPF

Windows Presentation Foundation (WPF) es un sistema de presentación de la próxima generación, para crear aplicaciones cliente de Windows que proporcionen una experiencia impactante para el usuario desde el punto de vista visual. Con WPF, puede crear una amplia gama de aplicaciones independientes y hospedadas en explorador. Un ejemplo es Contoso Healthcare Sample Application que se muestra en la ilustración siguiente.

Ejemplo Contoso Healthcare UI

El núcleo de WPF es un motor de representación basado en vectores e independiente de la resolución que se crea para sacar partido del hardware de gráficos moderno. WPF extiende el núcleo con un conjunto completo de características de desarrollo de aplicaciones que incluye Extensible Application Markup Language (XAML), controles, enlace de datos, diseño, gráficos 2-D y 3-D, animación, estilos, plantillas, documentos, multimedia, texto y tipografía. WPF se incluye en Microsoft .NET Framework, de modo que es posible compilar aplicaciones que incorporen otros elementos de la biblioteca de clases de .NET Framework.

Esta introducción está dirigida a personas que no conocen aún WPF, y en ella se abordan sus conceptos y capacidades principales. Los programadores de WPF experimentados que deseen revisar este marco de trabajo también la encontrarán de utilidad.

NotaNota

Para conocer las características nuevas y actualizadas de WPF en .NET Framework 4, vea Novedades de WPF versión 4.

Este tema contiene las secciones siguientes.

  • Programar con WPF
  • Código de lenguaje marcado y código subyacente
  • Aplicaciones
  • Controles
  • Acciones del usuario y comandos
  • Diseño
  • Enlace de datos
  • Gráficos
  • Animación
  • Multimedia
  • Texto y tipografía
  • Documentos
  • Personalizar las aplicaciones WPF
  • Procedimientos recomendados en WPF
  • Resumen
  • Introducciones y ejemplos recomendados
  • Temas relacionados

Programar con WPF

WPF constituye un subconjunto de tipos de .NET Framework en su mayoría ubicados en el espacio de nombres System.Windows. Si ha compilado previamente aplicaciones con .NET Framework mediante tecnologías administradas como ASP.NET y Windows Forms, los conceptos fundamentales de la programación en WPF deben resultarle familiares; creará instancias de clases, definirá propiedades, llamará a métodos y controlará eventos con el lenguaje de programación de .NET Framework que prefiera, como C# o Visual Basic.

Para admitir algunas de las funciones de WPF más eficaces y simplificar la experiencia de programación, WPF incluye construcciones de programación adicionales que mejoran las propiedades y los eventos: las propiedades de dependencia y los eventos enrutados. Para obtener más información acerca de las propiedades de dependencia, vea Información general sobre las propiedades de dependencia. Para obtener más información acerca de los eventos enrutados, vea Información general sobre eventos enrutados.

Código de lenguaje marcado y código subyacente

WPF proporciona mejoras de programación adicionales para el desarrollo de aplicaciones cliente de Windows. Una mejora evidente es la capacidad para programar una aplicación mediante código de lenguaje marcado y subyacente, una experiencia con la que resultará familiar a los programadores de ASP.NET. En general, se utiliza el lenguaje marcado Extensible Application Markup Language (XAML) para implementar la apariencia de una aplicación, y los lenguajes de programación administrados (subyacentes) para implementar su comportamiento. Esta separación entre la apariencia y el comportamiento aporta las ventajas siguientes:

  • Se reducen los costos de programación y mantenimiento, al no estar el marcado específico de la apariencia estrechamente relacionado con el código específico del comportamiento.

  • La programación es más eficaz porque los diseñadores pueden implementar la apariencia de una aplicación al mismo tiempo que los programadores implementan su comportamiento.

  • Se pueden usar varias herramientas de diseño para implementar y compartir el marcado XAML, a fin de responder a los requisitos de quienes colaboran en la programación de aplicaciones; Microsoft Expression Blend proporciona una experiencia apropiada para los diseñadores, mientras que Visual Studio 2005 está dirigido a los programadores.

  • La globalización y localización de las aplicaciones WPF se ha simplificado en gran medida (vea Información general sobre la localización y globalización de WPF).

A continuación, se muestra una introducción breve al código de lenguaje marcado y subyacente de WPF. Para obtener más información acerca de este modelo de programación, vea Información general sobre XAML (WPF) y Código subyacente y XAML en WPF.

Marcado

XAML es un lenguaje de marcado basado en XML que se utiliza para implementar la apariencia de una aplicación mediante declaración. Se suele utilizar para crear ventanas, cuadros de diálogo, páginas y controles de usuario, así como para rellenarlos con controles, formas y gráficos.

En el ejemplo siguiente se usa XAML para implementar la apariencia de una ventana que contiene un solo botón.

<Window
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    Title="Window with Button"
    Width="250" Height="100">

  <!-- Add button to window -->
  <Button Name="button">Click Me!</Button>

</Window>

En concreto, este código XAML define una ventana y un botón mediante los elementos Window y Button, respectivamente. Cada elemento se configura con atributos, como el atributo Title del elemento Window para especificar el texto de la barra de título de la ventana. En tiempo de ejecución, WPF convierte los elementos y atributos definidos en el marcado en instancias de clases de WPF. Por ejemplo, el elemento Window se convierte en una instancia de la clase Window cuya propiedad Title es el valor del atributo Title.

En la ilustración siguiente se muestra la user interface (UI) definida mediante el código XAML del ejemplo anterior.

Ventana que contiene un botón

Para obtener más información, vea Información general sobre XAML (WPF).

Puesto que XAML se basa en XML, la UI que se crea con este lenguaje se ensambla en una jerarquía de elementos anidados que se denomina árbol de elementos. El árbol de elementos proporciona una manera lógica e intuitiva de crear y administrar las UIs. Para obtener más información, vea Árboles en WPF.

Código subyacente

El comportamiento principal de una aplicación es implementar la funcionalidad que responde a las interacciones con el usuario, lo que incluye controlar los eventos (por ejemplo, hacer clic en un menú, una barra de herramientas o un botón) y llamar, en respuesta, a la lógica empresarial y de acceso a los datos. En WPF, este comportamiento se suele implementar en código asociado al marcado. Este tipo de código se denomina subyacente. En el ejemplo siguiente se muestran el código subyacente y el marcado actualizado del ejemplo anterior.

<Window
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.AWindow"
    Title="Window with Button"
    Width="250" Height="100">

  <!-- Add button to window -->
  <Button Name="button" Click="button_Click">Click Me!</Button>

</Window>

Namespace SDKSample

    Partial Public Class AWindow
        Inherits System.Windows.Window

        Public Sub New()

            ' InitializeComponent call is required to merge the UI
            ' that is defined in markup with this class, including 
            ' setting properties and registering event handlers
            InitializeComponent()

        End Sub

        Private Sub button_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)

            ' Show message box when button is clicked
            MessageBox.Show("Hello, Windows Presentation Foundation!")

        End Sub

    End Class

End Namespace
using System.Windows; // Window, RoutedEventArgs, MessageBox

namespace SDKSample
{
    public partial class AWindow : Window
    {
        public AWindow()
        {
            // InitializeComponent call is required to merge the UI
            // that is defined in markup with this class, including 
            // setting properties and registering event handlers
            InitializeComponent();
        }

        void button_Click(object sender, RoutedEventArgs e)
        {
            // Show message box when button is clicked
            MessageBox.Show("Hello, Windows Presentation Foundation!");
        }
    }
}

En este ejemplo, el código subyacente implementa una clase que se deriva de la clase Window. El atributo x:Class se usa para asociar el marcado a la clase de código subyacente. Se llama a InitializeComponent desde el constructor de la clase de código subyacente para combinar la interfaz de usuario que se define en el marcado con la clase de código subyacente. (InitializeComponent se genera automáticamente al compilar la aplicación, por lo que no se requiere su implementación manual). La combinación de x:Class e InitializeComponent garantiza que la implementación se inicializa correctamente cada vez que se crea. La clase de código subyacente también implementa un controlador de eventos para el evento Click del botón. Cuando se hace clic en el botón, el controlador de eventos muestra un cuadro de mensaje llamando al método MessageBox.Show.

En la ilustración siguiente se muestra el resultado de hacer clic en el botón.

MessageBox

Para obtener más información, vea Código subyacente y XAML en WPF.

Aplicaciones

.NET Framework, System.Windows, así como el marcado y el código subyacente, constituyen la base de la experiencia de desarrollo de aplicaciones en WPF. Además, WPF cuenta con características completas para crear experiencias de usuario con contenido enriquecido. Para empaquetar este contenido y distribuirlo a los usuarios en forma de "aplicaciones", WPF proporciona tipos y servicios denominados colectivamente el modelo de aplicaciones. El modelo de aplicación admite la programación de aplicaciones independientes y hospedadas en explorador.

Aplicaciones independientes

Para las aplicaciones independientes, puede utilizar la clase Window para crear las ventanas y cuadros de diálogo a los que se tiene acceso desde las barras de menús y las barras de herramientas. En la ilustración siguiente se muestra una aplicación independiente con una ventana principal y un cuadro de diálogo.

Ventana principal y cuadro de diálogo

Además, puede utilizar los cuadros de diálogo siguientes de WPF: MessageBox, OpenFileDialog, SaveFileDialog y PrintDialog.

Para obtener más información, vea Información general sobre ventanas de WPF.

Aplicaciones hospedadas en explorador

Para las aplicaciones hospedadas en explorador, denominadas XAML browser applications (XBAPs), puede crear páginas (Page) y funciones de página (PageFunction<T>) entre las que se puede navegar mediante hipervínculos (clases Hyperlink). En la ilustración siguiente se muestra una página de XBAP hospedada en Internet Explorer 7.

Dos páginas de una aplicación hospedada

Las aplicaciones WPF se pueden hospedar en Microsoft Internet Explorer 6 y Internet Explorer 7. WPF proporciona las dos opciones siguientes de hosts de navegación alternativos:

  • Frame, para hospedar islas de contenido navegable en páginas o ventanas.

  • NavigationWindow, para hospedar contenido navegable en una ventana completa.

Para obtener más información, vea Información general sobre navegación.

Clase Application

Tanto las XBAPs como las aplicaciones independientes suelen ser bastante complejas y necesitan servicios adicionales de ámbito de la aplicación, lo que incluye la administración del inicio y de la duración, así como propiedades y recursos compartidos. La clase Application encapsula todos estos servicios y algunos más, y solo se puede implementar mediante XAML, como se muestra en el ejemplo siguiente.

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

Este marcado es la definición de aplicación de una aplicación independiente, e indica a WPF que cree un objeto Application que abra MainWindow automáticamente cuando se inicie la aplicación.

Un concepto que es fundamental entender acerca de Application es que proporciona una plataforma común de compatibilidad para las aplicaciones independientes y hospedadas en explorador. Por ejemplo, el código XAML anterior podría utilizarlo una aplicación hospedada en explorador para navegar automáticamente a una página al iniciar una XBAP, como se muestra en el ejemplo siguiente.

<Application
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    StartupUri="HomePage.xaml" />

Para obtener más información, vea Información general sobre la administración de aplicaciones.

Seguridad

Dado que las XBAPs se hospedan en un explorador, la seguridad es importante. En particular, las XBAPs utilizan un recinto de seguridad de confianza parcial para aplicar restricciones menores o iguales a las que se imponen a las aplicaciones basadas en HTML. Además, todas las características de HTML que es seguro ejecutar desde las XBAPs con confianza parcial se han probado mediante un proceso de seguridad completo, que se detalla en Estrategia de seguridad de WPF: Ingeniería de seguridad.

Aún así, la mayoría de las características de WPF se pueden ejecutar con seguridad desde las XBAPs, como se describe en Seguridad de confianza parcial de WPF.

Controles

Las experiencias para el usuario proporcionadas por el modelo de aplicación son controles construidos. En WPF, un "control" es un término general que se aplica a una categoría de clases de WPF hospedadas en una ventana o una página, tienen una user interface (UI) e implementa un comportamiento determinado.

Para obtener más información, vea Controles.

Controles de WPF por función

A continuación se muestra la lista de controles WPF integrados.

Acciones del usuario y comandos

Los controles casi siempre detectan las acciones del usuario y responden a ellas. El sistema de entrada de WPF usa eventos directos y enrutados para admitir entradas de texto, la administración del enfoque y la posición del mouse. Para obtener más información, vea Información general sobre acciones del usuario.

Las aplicaciones a menudo tienen requisitos de entrada complejos. WPF proporciona un sistema de comandos que separa las acciones de entrada del usuario del código que responde a dichas acciones. Para obtener más información, vea Información general sobre comandos.

Diseño

Al crear una UI, se organizan los controles según su ubicación y tamaño para crear un diseño. Un requisito fundamental de cualquier diseño es adaptarse a los cambios de tamaño de la ventana y de configuración de pantalla. En lugar de obligarle a escribir código que adapte el diseño en estas circunstancias, WPF le proporciona un sistema de diseño extensible de primera clase.

La piedra angular del sistema de diseño es la situación relativa, que aumenta la capacidad de adaptación a los cambios en la configuración de las ventanas y de la pantalla. Además, el sistema de diseño administra la negociación entre los controles para determinar el diseño. La negociación es un proceso de dos pasos: en primer lugar, el control indica a su elemento primario qué ubicación y tamaño necesita; en segundo lugar, el elemento primario indica al control de qué espacio dispone.

El sistema de diseño se expone a los controles secundarios a través de las clases base de WPF. Para los diseños comunes como son las cuadrículas, el apilamiento y el acoplamiento, WPF incluye varios controles de diseño:

  • Canvas: los controles secundarios proporcionan su propio diseño.

  • DockPanel: los controles secundarios se alinean con los bordes del panel.

  • Grid: los controles secundarios se sitúan por filas y columnas.

  • StackPanel: los controles secundarios se apilan vertical u horizontalmente.

  • VirtualizingStackPanel: los controles secundarios se organizan en una vista "virtual" de una sola línea en sentido horizontal o vertical.

  • WrapPanel: los controles secundarios se sitúan por orden de izquierda a derecha y se ajustan a la línea siguiente cuando hay más controles de los que caben en la línea actual.

En el ejemplo siguiente se utiliza un control DockPanel para situar varios controles TextBox.

<Window
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.LayoutWindow"
    Title="Layout with the DockPanel" Height="143" Width="319">

  <!--DockPanel to layout four text boxes--> 
  <DockPanel>
    <TextBox DockPanel.Dock="Top">Dock = "Top"</TextBox>
    <TextBox DockPanel.Dock="Bottom">Dock = "Bottom"</TextBox>
    <TextBox DockPanel.Dock="Left">Dock = "Left"</TextBox>
    <TextBox Background="White">This TextBox "fills" the remaining space.</TextBox>
  </DockPanel>

</Window>

DockPanel permite que los controles secundarios TextBox le indiquen cómo se deben organizar. Para ello, DockPanel implementa una propiedad Dock que se expone a los controles secundarios, a fin de para permitir que cada uno de ellos especifique un estilo de acoplamiento.

NotaNota

Una propiedad implementada por un control principal para que la utilicen los controles secundarios es una construcción de WPF denominada propiedad asociada (vea Información general sobre propiedades asociadas).

En la ilustración siguiente se muestra el resultado del marcado XAML del ejemplo anterior.

Página de DockPanel

Para obtener más información, vea Sistema de diseño. Para obtener un ejemplo a modo de introducción, vea Ejemplo WPF Layout Gallery.

Enlace de datos

La mayoría de las aplicaciones se crean para proporcionar recursos a los usuarios que les permitan ver y editar los datos. Para aplicaciones WPF, el trabajo de almacenar los datos y tener acceso a ellos se proporciona mediante tecnologías existentes, como Microsoft SQL Server y ADO.NET. Después de obtener acceso a los datos y de cargarlos en los objetos administrados de una aplicación, comienza la tarea ardua de las aplicaciones WPF. En esencia, esto implica dos cosas:

  1. Copiar los datos desde los objetos administrados en los controles, donde los datos se pueden mostrar y editar.

  2. Asegurarse de que los cambios realizados en los datos mediante los controles se vuelvan a copiar en los objetos administrados.

Para simplificar el desarrollo de aplicaciones, WPF proporciona un motor de enlace de datos que realiza estos pasos automáticamente. La unidad que constituye el núcleo del motor de enlace de datos es la clase Binding, encargada de enlazar un control (el destino de enlace) a un objeto de datos (el origen de enlace). Esta relación se muestra en la ilustración siguiente.

Diagrama de enlace de datos básico

En el ejemplo siguiente se muestra cómo enlazar un control TextBox a una instancia de un objeto Person personalizado. La implementación de Person se muestra en el código siguiente.

Namespace SDKSample

    Class Person

        Private _name As String = "No Name"

        Public Property Name() As String
            Get
                Return _name
            End Get
            Set(ByVal value As String)
                _name = value
            End Set
        End Property

    End Class

End Namespace
namespace SDKSample
{
    class Person
    {
        string name = "No Name";

        public string Name
        {
            get { return name; }
            set { name = value; }
        }
    }
}

El marcado siguiente enlaza el control TextBox a una instancia de un objeto Person personalizado.

<Window
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.DataBindingWindow">


...


<!-- Bind the TextBox to the data source (TextBox.Text to Person.Name) -->
<TextBox Name="personNameTextBox" Text="{Binding Path=Name}" />


...


</Window>
Imports System.Windows ' Window

Namespace SDKSample

    Partial Public Class DataBindingWindow
        Inherits Window

        Public Sub New()
            InitializeComponent()

            ' Create Person data source
            Dim person As Person = New Person()

            ' Make data source available for binding
            Me.DataContext = person

        End Sub

    End Class

End Namespace
using System.Windows; // Window

namespace SDKSample
{
    public partial class DataBindingWindow : Window
    {
        public DataBindingWindow()
        {
            InitializeComponent();

            // Create Person data source
            Person person = new Person();

            // Make data source available for binding
            this.DataContext = person;
        }
    }
}

En este ejemplo, se crea una instancia de la clase Person en el código subyacente y se establece como el contexto de datos de DataBindingWindow. En el marcado, la propiedad Text de TextBox se enlaza a la propiedad Person.Name (mediante la sintaxis "{Binding ... }" de XAML). Este código XAML indica a WPF que enlace el control TextBox al objeto Person almacenado en la propiedad DataContext de la ventana.

El motor de enlace de datos de WPF proporciona compatibilidad adicional que incluye validación, ordenación, filtrado y agrupación. Además, el enlace de datos admite el uso de plantillas de datos, a fin de crear una UI personalizada para los datos enlazados cuando la UI mostrada por los controles estándar de WPF no es adecuada.

Para obtener más información, vea Información general sobre el enlace de datos. Para obtener un ejemplo a modo de introducción, vea Demo Data Binding.

Gráficos

WPF presenta un conjunto extenso, escalable y flexible de características de gráficos que aportan las ventajas siguientes:

  • Gráficos independientes de la resolución e independientes del dispositivo. La unidad de medida básica del sistema de gráficos de WPF es el píxel independiente del dispositivo, que es 1/96 de pulgada, independientemente de la resolución de pantalla real, y que proporciona la base para la representación independiente de la resolución y del dispositivo. Cada píxel independiente del dispositivo se escala automáticamente para coincidir con el valor de puntos por pulgada (ppp) del sistema en que se representa.

  • Precisión mejorada. El sistema de coordenadas de WPF se mide con números de punto flotante de precisión doble, en lugar de precisión sencilla. Las transformaciones y valores de opacidad también se expresan como de precisión doble. WPF admite además una gama de color amplia (scRGB) y ofrece compatibilidad integrada para la administración de entradas de diferentes espacios de color.

  • Compatibilidad con gráficos avanzados y animación. WPF simplifica la programación de gráficos administrando automáticamente las escenas de animación; no tendrá que preocuparse por el procesamiento de escenas, los bucles de presentación ni la interpolación bilineal. Además, WPF admite la comprobación de clics y proporciona compatibilidad plena con la composición alfa.

  • Aceleración de hardware. El sistema de gráficos de WPF saca partido del hardware de gráficos para minimizar el uso de la CPU.

Formas 2D

WPF proporciona una biblioteca de formas 2-D comunes dibujadas mediante vectores, como los rectángulos y las elipses que se muestran en la ilustración siguiente.

Elipses y rectángulos

Una función interesante de las formas es que no sirven únicamente para su presentación; las formas implementan muchas de las características que cabe esperar de los controles, incluida la entrada de datos desde el teclado y el mouse. En el ejemplo siguiente se muestra el control del evento MouseUp de una forma Ellipse.

<Window 
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.EllipseEventHandlingWindow"
    Title="Click the Ellipse">
    <Ellipse Name="clickableEllipse" Fill="Blue" MouseUp="clickableEllipse_MouseUp" />
</Window>
Imports System.Windows ' Window, MessageBox
Imports System.Windows.Input ' MouseButtonEventArgs

Namespace SDKSample

    Public Class EllipseEventHandlingWindow
        Inherits Window

        Public Sub New()
            InitializeComponent()
        End Sub

        Private Sub clickableEllipse_MouseUp(ByVal sender As Object, ByVal e As MouseButtonEventArgs)
            MessageBox.Show("You clicked the ellipse!")
        End Sub

    End Class

End Namespace
using System.Windows; // Window, MessageBox
using System.Windows.Input; // MouseButtonEventHandler

namespace SDKSample
{
    public partial class EllipseEventHandlingWindow : Window
    {
        public EllipseEventHandlingWindow()
        {
            InitializeComponent();
        }

        void clickableEllipse_MouseUp(object sender, MouseButtonEventArgs e)
        {
            // Display a message
            MessageBox.Show("You clicked the ellipse!");
        }
    }
}

En la ilustración siguiente se muestra lo que el código anterior genera.

Ventana con el texto "ha hecho clic en la elipse"

Para obtener más información, vea Información general sobre formas y dibujo básico en WPF. Para obtener un ejemplo introductorio, vea Shape Elements Sample.

Geometrías 2D

Las formas 2-D proporcionadas por WPF abarcan el conjunto estándar de formas básicas. Sin embargo, puede que sea preciso crear formas personalizadas para facilitar el diseño de una UI personalizada. Para este fin, WPF proporciona las geometrías. En la ilustración siguiente se muestra el uso de geometrías para crear una forma personalizada que se puede dibujar directamente, utilizar como un pincel o utilizar para recortar otras formas y controles.

Los objetos Path se pueden utilizar para dibujar formas cerradas o abiertas, varias formas o incluso formas curvas.

Los objetos Geometry se pueden utilizar para el recorte, la comprobación de visitas y la representación de datos de gráficos 2D.

Diversos usos de un trayecto

Para obtener más información, vea Información general sobre geometría. Para obtener un ejemplo introductorio, vea Geometries Sample.

Efectos 2D

Un subconjunto de las funciones  2-D de WPF son los efectos visuales, tales como degradados, mapas de bits, dibujos, pintar con vídeos, rotación, ajuste de escala y sesgo. Todas ellas se aplican mediante pinceles; en la siguiente ilustración se muestran algunos ejemplos.

Ilustración de diferentes pinceles

Para obtener más información, vea Información general sobre pinceles de WPF. Para obtener un ejemplo introductorio, vea Brushes Sample.

Representación 3D

WPF también incluye funcionalidad de representación 3-D que se integra con los gráficos 2-D para permitir la creación de UIs más interesantes y apasionantes. Por ejemplo, en la ilustración siguiente se muestran imágenes 2-D representadas en formas 3-D.

Captura de pantalla de ejemplo Visual3D

Para obtener más información, vea Información general sobre gráficos 3D. Para obtener un ejemplo introductorio, vea 3-D Solids Sample.

Animación

La compatibilidad de WPF con la animación permite hacer que los controles crezcan, tiemblen, giren o se desvanezcan, crear transiciones de página interesantes, y mucho más. Puede animar la mayoría de las clases de WPF, incluso las personalizadas. En la ilustración siguiente se muestra una animación simple en acción.

Imágenes de un cubo animado

Para obtener más información, vea Información general sobre animaciones. Para obtener un ejemplo introductorio, vea Animation Example Gallery.

Multimedia

Una manera de mostrar un contenido enriquecido es utilizar medios audiovisuales (multimedia). WPF proporciona compatibilidad especial con imágenes, vídeo y audio.

Imágenes

Las imágenes están presentes en la mayoría de las aplicaciones y WPF proporciona varias maneras de utilizarlas. En la ilustración siguiente se muestra una UI con un cuadro de lista que contiene imágenes en miniatura. Cuando se selecciona una miniatura, aparece la imagen a tamaño completo.

Imágenes en miniatura e imagen con tamaño total

Para obtener más información, vea Información general sobre imágenes.

Vídeo y audio

El control MediaElement es capaz de reproducir vídeo y audio y presenta la flexibilidad suficiente para constituir la base de un reproductor multimedia personalizado. El marcado XAML siguiente implementa un reproductor multimedia.

<MediaElement 
  Name="myMediaElement" 
  Source="media/wpf.wmv" 
  LoadedBehavior="Manual" 
  Width="350" Height="250" />

En la ventana de la ilustración siguiente se muestra el control MediaElement en acción.

Control MediaElement con audio y vídeo

Para obtener más información, vea Gráficos y multimedia.

Texto y tipografía

Para facilitar una representación de texto de gran calidad, WPF ofrece las características siguientes:

  • Compatibilidad con fuentes OpenType.

  • Mejoras de ClearType.

  • Alto rendimiento que saca partido de la aceleración de hardware.

  • Integración de texto con multimedia, gráficos y animación.

  • Compatibilidad con fuentes internacionales y mecanismos de reserva.

A modo de demostración de la integración del texto con gráficos, en la ilustración siguiente se muestra la aplicación de decoraciones al texto.

Texto con diversas decoraciones de texto

Para obtener más información, vea Tipografía en WPF.

Documentos

WPF incluye compatibilidad nativa para trabajar con tres tipos de documentos: documentos dinámicos, documentos estáticos y documentos XML Paper Specification (XPS). WPF también proporciona servicios para crear, ver, administrar, agregar, empaquetar e imprimir documentos.

Documentos dinámicos

Los documentos dinámicos se han diseñado para optimizar su presentación y legibilidad ajustando dinámicamente su contenido y modificando su flujo cuando se producen cambios en el tamaño de la ventana y la configuración de pantalla. En el marcado XAML siguiente se muestra la definición de FlowDocument.

<FlowDocument xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation">

  <Paragraph FontSize="18" FontWeight="Bold">Flow Document</Paragraph>

  <Paragraph>
    Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy
    nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi
    enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis
    nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure.
  </Paragraph>


...


</FlowDocument>

En el ejemplo siguiente se muestra cómo cargar un documento dinámico en FlowDocumentReader para leerlo, realizar búsquedas e imprimirlo.

<Window
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.FlowDocumentReaderWindow"
    Title="Flow Document Reader">
  <FlowDocumentReader Name="flowDocumentReader" />
</Window>
Imports System.Windows 'Window
Imports System.Windows.Documents 'FlowDocument
Imports System.IO 'FileStream, FileMode
Imports System.Windows.Markup 'XamlReader

Namespace SDKSample

    Public Class FlowDocumentReaderWindow
        Inherits Window

        Public Sub New()
            Me.InitializeComponent()
            Using stream1 As FileStream = New FileStream("AFlowDocument.xaml", _
                FileMode.Open, FileAccess.Read)
                Dim document1 As FlowDocument = _
                    TryCast(XamlReader.Load(stream1), FlowDocument)
                Me.flowDocumentReader.Document = document1
            End Using
        End Sub

    End Class

End Namespace
using System.Windows; // Window
using System.Windows.Documents; // FlowDocument
using System.IO; // FileStream, FileMode
using System.Windows.Markup; // XamlReader

namespace SDKSample
{
    public partial class FlowDocumentReaderWindow : System.Windows.Window
    {
        public FlowDocumentReaderWindow()
        {
            InitializeComponent();

            // Open the file that contains the FlowDocument
            using (FileStream xamlFile = new FileStream("AFlowDocument.xaml", 
                FileMode.Open, FileAccess.Read))
            {
                // Parse the file with the XamlReader.Load method
                FlowDocument content = XamlReader.Load(xamlFile) as FlowDocument;

                // Set the Document property to the parsed FlowDocument object
                this.flowDocumentReader.Document = content;
            }
        }
    }
}

En el ejemplo siguiente se muestra el resultado.

FlowDocument dentro de un control FlowDocumentReader

Para obtener más información, vea Información general sobre documentos dinámicos.

Documentos fijos

Los documentos fijos están destinados a aplicaciones que requieren una presentación con representación fiel (lo que se ve es lo que se obtiene, o WYSIWYG, en sus siglas en inglés) precisa, especialmente por lo que respecta a su impresión. Los usos típicos para los documentos fijos incluyen la creación de publicaciones, el procesamiento de textos y el diseño de formularios, donde es vital que se respete el diseño de página original.

Los documentos fijos conservan la organización precisa de su contenido de una manera independiente del dispositivo. Por ejemplo, un documento fijo mostrado en una pantalla de 96 puntos por pulgada (ppp) aparece exactamente igual que cuando se imprime en una impresora láser de 600 ppp o una máquina tipográfica fotográfica de 4800 ppp. El diseño permanece inalterado en todos los casos, aunque la calidad del documento varía según las funciones de cada dispositivo.

Para obtener más información, vea Documentos en WPF.

Documentos XPS

Los documentos XML Paper Specification (XPS) se basan en los documentos estáticos WPF. Los documentos XPS se describen con un esquema basado en XML que es esencialmente una representación paginada de papel electrónico. XPS es un formato de documento abierto, multiplataforma, cuyo propósito es facilitar la creación, el uso compartido, la impresión y el archivado de documentos paginados. Entre las características importantes de la tecnología XPS se incluyen:

  • Empaquetado de documentos XPS como archivos ZipPackage conformes con la especificación Open Packaging Conventions (OPC).

  • Hospedaje en aplicaciones independientes y basadas en explorador.

  • Generación y manipulación manuales de documentos XPS desde las aplicaciones WPF.

  • Representación de gran fidelidad gracias al establecimiento como destino de la máxima calidad del dispositivo de salida.

  • Puesta en cola para impresión de Windows Vista.

  • Enrutamiento directo de documentos a impresoras compatibles con XPS.

  • Integración de la UI con DocumentViewer.

En la ilustración siguiente se muestra un documento XPS mostrado en un control DocumentViewer.

Documento XPS dentro de un control DocumentViewer

DocumentViewer también permite a los usuarios cambiar la vista de los documentos XPS, realizar búsquedas en ellos e imprimirlos.

Para obtener más información, vea Documentos en WPF.

Anotaciones

Las anotaciones son notas o comentarios que se agregan a los documentos para marcar la información o resaltar elementos de interés, a fin de consultarlos más adelante. Aunque escribir notas en documentos impresos es fácil, la posibilidad de "escribir" notas en los documentos electrónicos con frecuencia es limitada o no está disponible en absoluto. Sin embargo, en WPF se proporciona un sistema de anotaciones que admite la inserción de notas rápidas y el resaltado. Además, estas anotaciones se pueden aplicar a documentos hospedados en el control DocumentViewer, como se muestra en la ilustración siguiente.

Aplicación de estilos a anotaciones

Para obtener más información, vea Información general sobre anotaciones.

Empaquetado

Las APIs System.IO.Packaging de WPF permiten que las aplicaciones organicen los datos, el contenido y los recursos en un único documento ZIP portátil, sencillo de distribuir y de fácil acceso. Es posible incluir firmas digitales para autenticar los elementos contenidos en un paquete y comprobar que el elemento firmado no se haya manipulado ni modificado. También puede cifrar los paquetes mediante la administración de derechos para restringir el acceso a la información protegida.

Para obtener más información, vea Documentos en WPF.

Impresión

.NET Framework incluye un subsistema de impresión al que WPF aporta, además, compatibilidad con el control de sistemas de impresión mejorados. Las mejoras de impresión incluyen las siguientes:

  • Instalación en tiempo real de servidores de impresión y colas remotos.

  • Detección dinámica de funciones de impresora.

  • Configuración dinámica de opciones de impresión.

  • Modificación del enrutamiento y las prioridades de los trabajos de impresión.

Los documentos XPS presenta, además, una mejora fundamental del rendimiento. La ruta de acceso de impresión de Microsoft Windows Graphics Device Interface (GDI) suele requerir dos conversiones:

  • La primera conversión del documento a un formato de procesador de impresión, como Enhanced Metafile (EMF).

  • Una segunda conversión al lenguaje de descripción de páginas de la impresora, como PCL o PostScript.

Sin embargo, los documentos XPS evitan estas conversiones porque un componente del formato de archivo XPS es un lenguaje de procesador de impresión y un lenguaje de descripción de páginas. Esta compatibilidad ayuda a reducir tamaño del archivo de cola y las cargas de las impresoras integradas en red.

Para obtener más información, vea Información general sobre impresión.

Personalizar las aplicaciones WPF

Hasta este punto, hemos estudiado los bloques de creación de WPF fundamentales para la programación de aplicaciones. El modelo de aplicación se utiliza para hospedar y distribuir el contenido de las aplicaciones, que está compuesto principalmente de controles. Para simplificar la organización de los controles en una UI y asegurarse de que la organización se conserve aunque se modifiquen el tamaño de la ventana y la configuración de pantalla, se utiliza el sistema de diseño de WPF. Dado que la mayoría de las aplicaciones permiten a los usuarios interactuar con los datos, los enlaces de datos se utilizan para reducir el trabajo de integración de la UI con esos datos. A fin de mejorar la apariencia visual de la aplicación, se utiliza toda la gama de gráficos, animación y multimedia que proporciona WPF. Por último, si la aplicación funciona a través de texto y documentos, puede utilizar las funciones de tipografía, documentos, anotación, empaquetado e impresión de WPF.

Sin embargo, con frecuencia estos elementos fundamentales no bastan para crear y administrar una experiencia del usuario realmente diferenciada y visualmente impactante. Puede que los controles de WPF no se integren con la apariencia deseada de la aplicación. Es posible que los datos no se muestren del modo más eficaz. La apariencia y el funcionamiento predeterminados de los temas de Windows pueden no ser adecuados para proporcionar la experiencia global del usuario con respecto a la aplicación. En muchos aspectos, una tecnología de presentación requiere la extensibilidad visual tanto como cualquier otro tipo de extensibilidad.

Por esta razón, WPF proporciona gran variedad de mecanismos para la creación de experiencias de usuario únicas, incluido un modelo de contenido enriquecido para los controles, desencadenadores, plantillas de controles y datos, estilos, recursos de la UI, temas y máscaras.

Modelo de contenido

El propósito principal de la mayoría de los controles de WPF es mostrar contenido. En WPF, el tipo y número de elementos que pueden constituir el contenido de un control se denomina el modelo de contenido del control. Algunos controles pueden contener un solo elemento y tipo de contenido; por ejemplo, el contenido de un control TextBox es un valor de tipo String que se asigna a la propiedad Text. En el ejemplo siguiente se establece el contenido de TextBox.

<Window 
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.TextBoxContentWindow"
    Title="TextBox Content">


...


<TextBox Text="This is the content of a TextBox." />


...


</Window>

En la ilustración siguiente se muestra el resultado.

Control TextBox que contiene texto

Otros controles, sin embargo, pueden contener varios elementos con tipos diferentes de contenido; el contenido de un control Button, especificado por la propiedad Content, puede contener gran variedad de elementos, entre los que se incluyen controles de diseño, texto, imágenes y formas. En el ejemplo siguiente se muestra un control Button con contenido que incluye DockPanel, Label, Border y MediaElement.

<Window 
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.ButtonContentWindow"
    Title="Button Content">


...


<Button Margin="20">
  <!-- Button Content -->
  <DockPanel Width="200" Height="180">
    <Label DockPanel.Dock="Top" HorizontalAlignment="Center">Click Me!</Label>
    <Border Background="Black" BorderBrush="Yellow" BorderThickness="2" 
      CornerRadius="2" Margin="5">
      <MediaElement Source="media/wpf.wmv" Stretch="Fill" />
    </Border>
  </DockPanel>
</Button>


...


</Window>

En la ilustración siguiente se muestra el contenido de este botón.

Botón que tiene varios tipos de contenido

Para obtener más información sobre los tipos de contenido admitidos por los diversos controles, vea Modelo de contenido de WPF.

Desencadenadores

Aunque el propósito principal del marcado XAML es implementar la apariencia de una aplicación, también puede utilizar XAML para implementar algunos aspectos del comportamiento de una aplicación. Un ejemplo de ello es el uso de desencadenadores para cambiar la apariencia de una aplicación de acuerdo con las interacciones con el usuario. Para obtener más información, vea "Desencadenadores" en Aplicar estilos y plantillas.

Plantillas de control

Las UIs predeterminadas para los controles WPF suelen construirse a partir de otros controles y formas. Por ejemplo, un control Button está compuesto de los controles ButtonChrome y ContentPresenter. ButtonChrome proporciona la apariencia del botón estándar, mientras que ContentPresenter muestra el contenido del botón, especificado por la propiedad Content.

A veces, la apariencia predeterminada de un control puede ser incongruente con la apariencia global de una aplicación. En este caso, puede utilizar una plantilla de control ControlTemplate para cambiar la apariencia de la UI del control sin modificar su contenido ni su comportamiento.

En el ejemplo siguiente se muestra cómo cambiar la apariencia de un control Button mediante ControlTemplate.

<Window 
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
  x:Class="SDKSample.ControlTemplateButtonWindow"
  Title="Button with Control Template" Height="158" Width="290">

  <!-- Button using an ellipse -->
  <Button Content="Click Me!" Click="button_Click">
    <Button.Template>
      <ControlTemplate TargetType="{x:Type Button}">
        <Grid Margin="5">
          <Ellipse Stroke="DarkBlue" StrokeThickness="2">
            <Ellipse.Fill>
              <RadialGradientBrush Center="0.3,0.2" RadiusX="0.5" RadiusY="0.5">
                <GradientStop Color="Azure" Offset="0.1" />
                <GradientStop Color="CornflowerBlue" Offset="1.1" />
              </RadialGradientBrush>
            </Ellipse.Fill>
          </Ellipse>
          <ContentPresenter Name="content" HorizontalAlignment="Center" 
            VerticalAlignment="Center"/>
        </Grid>
      </ControlTemplate>
    </Button.Template>

  </Button>

</Window>
Imports System.Windows ' Window, RoutedEventArgs, MessageBox

Namespace SDKSample

    Public Class ControlTemplateButtonWindow
        Inherits Window

        Public Sub New()

            InitializeComponent()

        End Sub

        Private Sub button_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
            MessageBox.Show("Hello, Windows Presentation Foundation!")
        End Sub

    End Class

End Namespace
using System.Windows; // Window, RoutedEventArgs, MessageBox

namespace SDKSample
{
    public partial class ControlTemplateButtonWindow : Window
    {
        public ControlTemplateButtonWindow()
        {
            InitializeComponent();
        }

        void button_Click(object sender, RoutedEventArgs e)
        {
            // Show message box when button is clicked
            MessageBox.Show("Hello, Windows Presentation Foundation!");
        }
    }
}

En este ejemplo, la UI del botón predeterminado se ha reemplazado por una forma Ellipse que tiene un borde azul marino y se rellena mediante RadialGradientBrush. El control ContentPresenter muestra el contenido de Button, "Click Me!". Cuando se hace clic en Button, el evento Click todavía se provoca como parte del comportamiento predeterminado del control Button. El resultado se muestra en la ilustración siguiente.

Botón elíptico y una segunda ventana

Para obtener más información, vea ControlTemplate. Para obtener un ejemplo a modo de introducción, vea Styling with ControlTemplates Sample.

Plantillas de datos

Mientras que una plantilla de control permite especificar la apariencia de un control, una plantilla de datos permite especificar la apariencia del contenido del control. Las plantillas de datos se utilizan con frecuencia para mejorar la manera de mostrar los datos enlazados. En la ilustración siguiente se muestra la apariencia predeterminada de un control ListBox enlazado a una colección de objetos Task, donde cada tarea tiene un nombre, descripción y prioridad.

Cuadro de lista con el aspecto predeterminado

La apariencia predeterminada es la que cabría esperar de un control ListBox. Sin embargo, la apariencia predeterminada de cada tarea contiene únicamente el nombre de tarea. Para mostrar el nombre de tarea, la descripción y la prioridad, la apariencia predeterminada de los elementos de lista enlazados al control ListBox se debe modificar, mediante DataTemplate. En el código XAML siguiente se define una plantilla de datos DataTemplate, que se aplica a cada tarea mediante el atributo ItemTemplate.

<Window
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
  x:Class="SDKSample.DataTemplateWindow"
  Title="With a Data Template">


...


<Window.Resources>
  <!-- Data Template (applied to each bound task item in the task collection) -->
  <DataTemplate x:Key="myTaskTemplate">
    <Border Name="border" BorderBrush="DarkSlateBlue" BorderThickness="2" 
      CornerRadius="2" Padding="5" Margin="5">
      <Grid>
        <Grid.RowDefinitions>
          <RowDefinition/>
          <RowDefinition/>
          <RowDefinition/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
          <ColumnDefinition Width="Auto" />
          <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <TextBlock Grid.Row="0" Grid.Column="0" Padding="0,0,5,0" Text="Task Name:"/>
        <TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding Path=TaskName}"/>
        <TextBlock Grid.Row="1" Grid.Column="0" Padding="0,0,5,0" Text="Description:"/>
        <TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding Path=Description}"/>
        <TextBlock Grid.Row="2" Grid.Column="0" Padding="0,0,5,0" Text="Priority:"/>
        <TextBlock Grid.Row="2" Grid.Column="1" Text="{Binding Path=Priority}"/>
      </Grid>
    </Border>  
  </DataTemplate>
</Window.Resources>


...


<!-- UI -->
<DockPanel>
  <!-- Title -->
  <Label DockPanel.Dock="Top" FontSize="18" Margin="5" Content="My Task List:"/>

  <!-- Data template is specified by the ItemTemplate attribute -->
  <ListBox 
    ItemsSource="{Binding}" 
    ItemTemplate="{StaticResource myTaskTemplate}" 
    HorizontalContentAlignment="Stretch" 
    IsSynchronizedWithCurrentItem="True" 
    Margin="5,0,5,5" />

</DockPanel>


...


</Window>

En la ilustración siguiente se muestra el efecto de este código.

Cuadro de lista que usa una plantilla de datos

Observe que ListBox ha conservado su comportamiento y su apariencia global; únicamente ha cambiado la apariencia del contenido mostrado por el cuadro de lista.

Para obtener más información, vea Información general sobre plantillas de datos. Para obtener un ejemplo a modo de introducción, vea Ejemplo Introduction to Data Templating.

Estilos

Los estilos permiten a los desarrolladores y diseñadores normalizar la apariencia específica de un producto. WPF proporciona un modelo de estilo fuerte, cuya base es el elemento Style. En el ejemplo siguiente se crea un estilo que establece el color de fondo de todos los controles Button de una ventana en Orange.

<Window
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.StyleWindow"
    Title="Styles">


...


<!-- Style that will be applied to all buttons -->
<Style TargetType="{x:Type Button}">
  <Setter Property="Background" Value="Orange" />
  <Setter Property="BorderBrush" Value="Crimson" />
  <Setter Property="FontSize" Value="20" />
  <Setter Property="FontWeight" Value="Bold" />
  <Setter Property="Margin" Value="5" />
</Style>


...


<!-- This button will have the style applied to it -->
<Button>Click Me!</Button>

<!-- This label will not have the style applied to it -->
<Label>Don't Click Me!</Label>

<!-- This button will have the style applied to it -->
<Button>Click Me!</Button>


...


</Window>

Dado que este estilo tiene como destino todos los controles Button, se aplica automáticamente a todos los botones de la ventana, como se muestra en la ilustración siguiente.

Dos botones de color naranja

Para obtener más información, vea Aplicar estilos y plantillas. Para obtener un ejemplo a modo de introducción, vea Ejemplo Introduction to Styling and Templating.

Recursos

Los controles de una aplicación deben tener la misma apariencia, que puede incluir todo tipo de recursos, desde fuentes y colores de fondo hasta plantillas de control, pasando por las plantillas de datos y los estilos. Puede utilizar la compatibilidad de WPF con los recursos de user interface (UI) para encapsular estos recursos en una ubicación única y poder reutilizarlos.

En el ejemplo siguiente se define un color de fondo común que es compartido por los controles Button y Label.

<Window
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.ResourcesWindow"
    Title="Resources Window">

  <!-- Define window-scoped background color resource -->
  <Window.Resources>
    <SolidColorBrush x:Key="defaultBackground" Color="Red" />
  </Window.Resources>


...


<!-- Button background is defined by window-scoped resource -->
<Button Background="{StaticResource defaultBackground}">One Button</Button>

<!-- Label background is defined by window-scoped resource -->
<Label Background="{StaticResource defaultBackground}">One Label</Label>


...


</Window>

En este ejemplo se implementa un recurso de color de fondo mediante el elemento de propiedad Window.Resources. Este recurso está disponible para todos los elementos secundarios de Window. Existe gran variedad de ámbitos de recursos, incluidos los siguiente, que se muestran en el orden en que se resuelven:

  1. Un control individual (que utiliza la propiedad FrameworkElement.Resources heredada).

  2. Window o Page (que también utiliza la propiedad FrameworkElement.Resources heredada).

  3. Application (que utiliza la propiedad Application.Resources).

La variedad de ámbitos aporta flexibilidad al programador con respecto a la manera de definir y compartir los recursos.

Como alternativa a la asociación directa de los recursos a un ámbito determinado, puede empaquetar uno o varios recursos mediante un ResourceDictionary independiente al que puede hacer referencia en otras partes de una aplicación. En el ejemplo siguiente se define un color de fondo predeterminado en un diccionario de recursos.

<ResourceDictionary 
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml">

  <!-- Define background color resource -->
  <SolidColorBrush x:Key="defaultBackground" Color="Red" />

  <!-- Define other resources -->


...


</ResourceDictionary>

En el ejemplo siguiente se hace referencia al diccionario de recursos definido en el ejemplo anterior para compartirlo en toda la aplicación.

<Application
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.App">

  <Application.Resources>
    <ResourceDictionary>
      <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="BackgroundColorResources.xaml"/>
      </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
  </Application.Resources>


...


</Application>

Los recursos y diccionarios de recursos constituyen el fundamento de la compatibilidad de WPF con los temas y las máscaras.

Para obtener más información, vea Información general sobre recursos.

Temas y máscaras

Desde una perspectiva visual, un tema define la apariencia global de Windows y de las aplicaciones que se ejecutan en su seno. Windows incluye varios temas. Por ejemplo, Microsoft Windows XP se distribuye con los temas clásicos de Windows XP y Windows, mientras que Windows Vista se distribuye con los temas clásicos de Windows Vista y Windows. La apariencia definida por un tema establece la apariencia predeterminada de una aplicación WPF. Sin embargo, WPF no se integra directamente con los temas de Windows. Dado que la apariencia de WPF se define mediante plantillas, WPF incluye una plantilla para cada uno de los temas conocidos de Windows, como Aero (Windows Vista), Clásico (Microsoft Windows 2000), Luna (Microsoft Windows XP) y Royale (Microsoft Windows XP Media Center Edition 2005). están empaquetados en diccionarios de recursos que se resuelven cuando no se encuentran los recursos correspondientes en una aplicación. Muchas aplicaciones se basan en estos temas para definir su apariencia visual; mantener la coherencia con la apariencia de Windows ayuda a los usuarios a familiarizarse con las aplicaciones más fácilmente.

Por otro lado, la experiencia del usuario para algunas aplicaciones no procede necesariamente de los temas estándar. Por ejemplo, Microsoft Windows Media Player funciona a través de datos de audio y vídeo y saca partido de un estilo diferente de experiencia del usuario. Tales UIs tienden a proporcionar temas personalizados, específicos de cada aplicación. Se denominan máscaras, y las aplicaciones con máscaras suelen proporcionar enlaces que permiten a los usuarios personalizar diversos aspectos de la máscara. Microsoft Windows Media Player tiene varias máscaras prefabricadas, así como una serie de máscaras de otros fabricantes.

Tanto los temas como las máscaras de WPF se definen con toda facilidad mediante los diccionarios de recursos. En el ejemplo siguiente se muestran ejemplos de definiciones de máscaras.

<!-- Blue Skin -->
<ResourceDictionary
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:SDKSample">
  <Style TargetType="{x:Type Button}">
    <Setter Property="Background" Value="Blue" />
  </Style>


...


</ResourceDictionary>
<!-- Yellow Skin -->
<ResourceDictionary
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:SDKSample">
  <Style TargetType="{x:Type Button}">
    <Setter Property="Background" Value="Yellow" />
  </Style>


...


</ResourceDictionary>

Para obtener más información, vea la sección sobre temas y recursos compartidos en Aplicar estilos y plantillas.

Controles personalizados

Aunque WPF proporciona una amplísima compatibilidad con funciones de personalización, puede encontrar situaciones en que los controles existentes de WPF no satisfagan las necesidades de la aplicación o de los usuarios. Esto puede suceder cuando:

  • La UI que necesita no se puede crear personalizando la apariencia y el funcionamiento de las implementaciones de WPF existentes.

  • Las implementaciones de WPF existentes no admiten el comportamiento que se necesita (o lo admiten, pero no fácilmente).

Sin embargo, en este punto puede sacar partido de uno de los tres modelos de WPF para crear un nuevo control. Cada modelo está destinado a un escenario concreto y exige que el control personalizado se derive de una clase base de WPF determinada. A continuación se muestran los tres modelos:

  • Modelo de control de usuario. El control personalizado se deriva de UserControl y se crea a partir de uno o varios controles.

  • Modelo de control. El control personalizado se deriva de Control y se utiliza para generar implementaciones que separan su comportamiento de su apariencia mediante plantillas, de un modo muy similar a la mayoría de los controles de WPF. Al derivarse de Control, aporta mayor libertad para la creación de una UI personalizada que los controles de usuario, pero puede requerir más esfuerzo.

  • Modelo de elemento de marco de trabajo. Un control personalizado se deriva de FrameworkElement cuando su apariencia se define mediante la lógica de representación personalizada (no mediante plantillas).

En el ejemplo siguiente se muestra un control numérico personalizado de arriba/abajo derivado de UserControl.

<UserControl
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
  x:Class="SDKSample.NumericUpDown">

  <Grid>

    <Grid.RowDefinitions>
      <RowDefinition/>
      <RowDefinition/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
      <ColumnDefinition/>
      <ColumnDefinition/>
    </Grid.ColumnDefinitions>

    <!-- Value text box -->
    <Border BorderThickness="1" BorderBrush="Gray" Margin="2" Grid.RowSpan="2" 
      VerticalAlignment="Center" HorizontalAlignment="Stretch">
      <TextBlock Name="valueText" Width="60" TextAlignment="Right" Padding="5"/>
    </Border>

    <!-- Up/Down buttons -->
    <RepeatButton Name="upButton" Click="upButton_Click" Grid.Column="1" 
      Grid.Row="0">Up</RepeatButton>
    <RepeatButton Name="downButton" Click="downButton_Click" Grid.Column="1" 
      Grid.Row="1">Down</RepeatButton>

  </Grid>

</UserControl>
imports System 'EventArgs
imports System.Windows 'DependencyObject, DependencyPropertyChangedEventArgs, 
                       ' FrameworkPropertyMetadata, PropertyChangedCallback, 
                       ' RoutedPropertyChangedEventArgs
imports System.Windows.Controls 'UserControl

Namespace SDKSample

    ' Interaction logic for NumericUpDown.xaml
    Partial Public Class NumericUpDown
        Inherits System.Windows.Controls.UserControl

        'NumericUpDown user control implementation


...



    End Class

End Namespace
using System; // EventArgs
using System.Windows; // DependencyObject, DependencyPropertyChangedEventArgs,
                      // FrameworkPropertyMetadata, PropertyChangedCallback, 
                      // RoutedPropertyChangedEventArgs
using System.Windows.Controls; // UserControl

namespace SDKSample
{
    public partial class NumericUpDown : UserControl
    {
        // NumericUpDown user control implementation


...


    }
}

En el ejemplo siguiente se muestra el código XAML necesario para incorporar el control de usuario a una ventana (Window).

<Window
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.UserControlWindow"
    xmlns:local="clr-namespace:SDKSample" 
    Title="User Control Window">


...


<!-- Numeric Up/Down user control -->
<local:NumericUpDown />


...


</Window>

En la ilustración siguiente se muestra el control NumericUpDown hospedado en una ventana Window.

UserControl personalizado

Para obtener más información sobre controles personalizados, vea Información general sobre la creación de controles.

Procedimientos recomendados en WPF

Como sucede con cualquier plataforma de programación, WPF se puede utilizar de diversas maneras para lograr el resultado deseado. A fin de asegurarse de que sus aplicaciones WPF proporcionen la experiencia de usuario necesaria y cumplan las exigencias del público en general, existen procedimientos recomendados de accesibilidad, globalización y localización, y rendimiento. Para obtener más información, vea las secciones siguientes:

Resumen

WPF es una completa tecnología de presentación para generar gran variedad aplicaciones cliente impactantes desde el punto de vista visual. En esta introducción se ha proporcionado una introducción general a las principales características de WPF.

El paso siguiente consiste en generar aplicaciones WPF.

Durante el proceso de creación, puede consultar de nuevo esta introducción para repasar las características clave y encontrar referencias a artículos donde se abordan en mayor profundidad todas las características tratadas en esta introducción.

Introducciones y ejemplos recomendados

En esta introducción se mencionan las introducciones y los ejemplos siguientes.

Temas de introducción

Procedimientos de accesibilidad recomendados

Información general sobre la administración de aplicaciones

Información general sobre comandos

Controles

Información general sobre el enlace de datos

Información general sobre las propiedades de dependencia

Documentos en WPF

Información general sobre acciones del usuario

Sistema de diseño

Información general sobre navegación

Información general sobre impresión

Información general sobre recursos

Información general sobre eventos enrutados

Aplicar estilos y plantillas

Tipografía en WPF

Seguridad (WPF)

Información general sobre ventanas de WPF

Modelo de contenido de WPF

Información general sobre la localización y globalización de WPF

Gráficos y multimedia

Ejemplos

3-D Solids Sample

Animation Example Gallery

Brushes Sample

Data Binding Demo

Geometries Sample

Introduction to Data Templating Sample

Introduction to Styling and Templating Sample

Shape Elements Sample

Styling with ControlTemplates Sample

WPF Layout Gallery Sample

Vea también

Conceptos

Tutorial: Introducción a WPF

Comentarios de la comunidad de WPF