84
Contraer todo Código: Todos Windows Presentation Foundation Introducción a Windows Presentation Foundation Vea también Enviar comentarios 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. Algunos ejemplos de ello son Yahoo! Messenger y New York Times Reader , así como la aplicación de ejemplo para atención sanitaria, Contoso Healthcare Sample Application que se muestra en la ilustración siguiente. El núcleo de WPF es un motor de representación independiente de la resolución y basado en vectores construido para aprovechar al máximo el hardware de gráficos moderno. WPF amplía el núcleo con un completo conjunto de características de programación de aplicaciones, entre las que se incluyen Lenguaje de marcado de aplicaciones extensible (XAML), controles, enlaces de datos, diseño, gráficos 2D y 3D, animación, estilos, plantillas, documentos, multimedia, texto y tipografía. WPF se incluye en Microsoft .NET Framework, lo que permite crear 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. 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 Nota: Para conocer las características nuevas y actualizadas de WPF en .NET Framework 3.5, vea Lo nuevo en Windows Presentation Foundation versión 3.5 . WPF constituye un subconjunto de tipos de .NET Framework, en su mayoría contenidos en el espacio de nombres de System.Windows . Si

WPF MSDN 2008

Embed Size (px)

Citation preview

Contraer todo Código: Todos

Windows Presentation Foundation

Introducción a Windows Presentation FoundationVea también Enviar comentarios

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. Algunos ejemplos de ello son Yahoo! Messenger y New York Times Reader, así como la aplicación de ejemplo para atención sanitaria, Contoso Healthcare Sample Application que se muestra en la ilustración siguiente.

El núcleo de WPF es un motor de representación independiente de la resolución y basado en vectores construido para aprovechar al máximo el hardware de gráficos moderno. WPF amplía el núcleo con un completo conjunto de características de programación de aplicaciones, entre las que se incluyen Lenguaje de marcado de aplicaciones extensible (XAML), controles, enlaces de datos, diseño, gráficos 2D y 3D, animación, estilos, plantillas, documentos, multimedia, texto y tipografía. WPF se incluye en Microsoft .NET Framework, lo que permite crear 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.

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

Nota:

Para conocer las características nuevas y actualizadas de WPF en .NET Framework 3.5, vea Lo nuevo en Windows Presentation Foundation versión 3.5.

WPF constituye un subconjunto de tipos de .NET Framework, en su mayoría contenidos en el espacio de nombres de System.Windows. Si

Código de lenguaje marcado y código subyacente

ha creado previamente aplicaciones con .NET Framework mediante tecnologías administradas como ASP.NET y formularios 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.

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 Lenguaje de marcado de aplicaciones extensible (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 utilizar varias herramientas de diseño para implementar y compartir el lenguaje marcado XAML, a fin de responder a los requisitos de los colaboradores de 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 y Código subyacente y XAML.

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 utiliza XAML para implementar la apariencia de una ventana que contiene un solo botón.

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 los 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 interfaz de usuario (UI) definida mediante el código XAML del ejemplo anterior.

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

Puesto que XAML se basa en XML, la interfaz de usuario 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.

XAML Copiar código

<Window

xmlns="http://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>

XAML Copiar código

<Window

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://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>

Aplicaciones

En este ejemplo, el código subyacente implementa una clase que se deriva de la clase Window. El atributo x:Class se utiliza 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 definida en el marcado con la clase de código subyacente. ((InitializeComponent se genera automáticamente al generar 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.

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

</Window>

C# Copiar código

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!");

}

}

}

Visual Basic Copiar código

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

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

.NET Framework, System.Windows, así como el código de lenguaje marcado y subyacente, constituyen la base de la experiencia de programación 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 aplicación. 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.

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 Aplicaciones del explorador XAML (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.

Las aplicaciones WPF se pueden hospedar en Internet Explorer 7 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 presentar la complejidad suficiente para necesitar servicios adicionales de ámbito de la aplicación, lo que incluye administración del inicio y de la duración, así como las propiedades y los recursos compartidos. La clase Application incluye todos estos servicios y más, y se puede implementar sólo mediante XAML, como se muestra en el ejemplo siguiente.

Este código de lenguaje marcado es la definición de aplicación de una aplicación independiente, e indica a WPF que cree un objeto Application que abre MainWindow automáticamente cuando se inicia 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.

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

XAML Copiar código

<Application

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

StartupUri="MainWindow.xaml" />

XAML Copiar código

<Application

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

StartupUri="HomePage.xaml" />

Controles

Acciones del usuario y comandos

Diseño

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 Windows Presentation Foundation: 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 en Windows Presentation Foundation.

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 interfaz de usuario (UI) e implementa un comportamiento determinado.

Para obtener más información, vea Información general sobre controles. Para ver ejemplos de introducción, vea Ejemplos de Control Library.

Lista controles de WPF

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

� Botones: Button y RepeatButton.

� Cuadros de diálogo: OpenFileDialog, PrintDialog y SaveFileDialog.

� Entradas manuscritas digitales: InkCanvas y InkPresenter.

� Documentos: DocumentViewer, FlowDocumentPageViewer, FlowDocumentReader, FlowDocumentScrollViewer y StickyNoteControl.

� Entrada: TextBox, RichTextBox y PasswordBox.

� Diseño: Border, BulletDecorator, Canvas, DockPanel, Expander, Grid, GridView, GridSplitter, GroupBox, Panel, ResizeGrip, Separator, ScrollBar, ScrollViewer, StackPanel, Thumb, Viewbox, VirtualizingStackPanel, Window y WrapPanel.

� Multimedia: Image, MediaElement y SoundPlayerAction.

� Menús: ContextMenu, Menu y ToolBar.

� Navegación: Frame, Hyperlink, Page, NavigationWindow y TabControl.

� Selección: CheckBox, ComboBox, ListBox, TreeView y RadioButton, Slider.

� Información para el usuario: AccessText, Label, Popup, ProgressBar, StatusBar, TextBlock y ToolTip.

Los controles casi siempre detectan las acciones del usuario y responden a ellas. El sistema de entrada de WPF utiliza 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 suelen tener requisitos de entrada complejos. WPF proporciona un sistema de comandos que separa las acciones de entrada del usuario del código que responde a esas acciones. Para obtener más información, vea Información general sobre comandos.

Al crear una interfaz de usuario, 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 mediante 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.

XAML Copiar código

<Window

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://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>

Enlace de datos

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.

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

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

Nota:

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

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 a 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 la programación 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 del enlace) a un objeto de datos (el origen del enlace). Esta relación se muestra en la ilustración siguiente.

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.

C# Copiar código

namespace SDKSample

{

class Person

{

string name = "No Name";

public string Name

{

get { return name; }

set { name = value; }

}

}

}

Visual Basic Copiar código

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

Gráficos

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

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 interfaz de usuario personalizada para los datos enlazados cuando la interfaz de usuario 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 ver un ejemplo de introducción, vea Demo Data Binding.

XAML Copiar código

<Window

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://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>

C# Copiar código

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;

}

}

}

Visual Basic Copiar código

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

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 simple. Las transformaciones y los valores de opacidad también se expresan como doble precisión. WPF admite también una amplia gama de colores (scRGB) y proporciona compatibilidad integrada para administrar las entradas desde espacios de color diferentes.

� 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 representació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 2D comunes dibujadas mediante vectores, como los rectángulos y las elipses que se muestran en la ilustración siguiente.

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.

XAML Copiar código

<Window

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

x:Class="SDKSample.EllipseEventHandlingWindow"

Title="Click the Ellipse">

<Ellipse Name="clickableEllipse" Fill="Blue" MouseUp="clickableEllipse_MouseUp" />

</Window>

C# Copiar código

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!");

}

}

}

Visual Basic Copiar código

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

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

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

Geometrías 2D

Las formas 2D 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 interfaz de usuario 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.

Para obtener más información, vea Información general sobre geometría. Para ver un ejemplo de introducción, vea Ejemplo Geometries.

Efectos 2D

Un subconjunto de las funciones 2D 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.

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

Representación 3D

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

Animación

Multimedia

Para obtener más información, vea Información general sobre gráficos 3D. Para ver un ejemplo de introducción, vea Ejemplo 3-D Solids.

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.

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

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 interfaz de usuario con un cuadro de lista que contiene imágenes en miniatura. Cuando se selecciona una miniatura, aparece la imagen a tamaño completo.

Texto y tipografía

Para obtener más información, vea Información general sobre imágenes. Para ver un ejemplo de introducción, vea Demo WPF Photo Viewer.

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.

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

Para obtener más información, vea Información general sobre características de gráficos, animación y multimedia en WPF. Para ver un ejemplo de introducción, vea Ejemplo Media Gallery.

XAML Copiar código

<MediaElement

Name="myMediaElement"

Source="media/wpf.wmv"

LoadedBehavior="Manual"

Width="350" Height="250" />

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

Documentos

texto.

Para obtener más información, vea Tipografía en Windows Presentation Foundation. Para ver ejemplos de introducción, vea Ejemplos de tipografía.

WPF permite trabajar de forma nativa con tres tipos de documentos: documentos de flujo, documentos fijos y documentos de XML Paper Specification (XPS). WPF proporciona también servicios para crear, ver, administrar, anotar, 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.

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

XAML Copiar código

<FlowDocument xmlns="http://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>

XAML Copiar código

<Window

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

x:Class="SDKSample.FlowDocumentReaderWindow"

Title="Flow Document Reader">

<FlowDocumentReader Name="flowDocumentReader" />

</Window>

C# Copiar código

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

En el ejemplo siguiente se muestra el resultado.

Para obtener más información, vea Información general sobre documentos dinámicos. Para ver un ejemplo de introducción, vea Ejemplo FlowDocument Properties.

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 Windows Presentation Foundation.

Documentos XPS

Los documentos de XML Paper Specification (XPS) se basan en documentos fijos de WPF. Los documentos de XPS se describen con un esquema basado en XML que básicamente es una representación en forma de página de documentos electrónicos. XPS es un formato de documento abierto habilitado para varios exploradores y diseñado para facilitar la creación, el uso compartido, la impresión y el almacenamiento 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 interfaz de usuario con DocumentViewer.

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

this.flowDocumentReader.Document = content;

}

}

}

}

Visual Basic Copiar código

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

Personalizar las aplicaciones WPF

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 Windows Presentation Foundation. Para ver un ejemplo de introducción, vea Ejemplo Creating an XPS Document.

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.

Para obtener más información, vea Información general sobre anotaciones. Para ver un ejemplo de introducción, vea Ejemplo Document Serialization.

Empaquetado

Las API 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 Windows Presentation Foundation. Para ver ejemplos, vea Ejemplos de empaquetado.

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 Interfaz de dispositivo gráfico de Microsoft Windows (GDI) de impresión suele requerir dos conversiones:

� La primera conversión del documento a un formato de procesador de impresión, como Metarchivo mejorado (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. Para ver un ejemplo de introducción, vea Printing an XPS Document.

Hasta este punto, hemos estudiado las unidades 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 interfaz de usuario 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 parte 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 interfaz de usuario 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 WPF admite. 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 interfaz de usuario, 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 está asignado a la propiedad Text. En el ejemplo siguiente se establece el contenido de TextBox.

En la ilustración siguiente se muestra el resultado.

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.

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

XAML Copiar código

<Window

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

x:Class="SDKSample.TextBoxContentWindow"

Title="TextBox Content">

...

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

...

</Window>

XAML Copiar código

<Window

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://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>

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

XAML Copiar código

<Window

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://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>

C# Copiar código

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 interfaz de usuario 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 del control Button, "Click Me!" (¡Haga clic aquí!). Al hacer clic en Button, se provoca como siempre el evento Click, que forma parte del comportamiento predeterminado del control Button. El resultado se muestra en la ilustración siguiente.

Para obtener más información, vea ControlTemplate. Para ver un ejemplo de introducción, vea Ejemplo Styling with ControlTemplates.

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.

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.

}

}

}

Visual Basic Copiar código

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

XAML Copiar código

<Window

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

x:Class="SDKSample.DataTemplateWindow"

Title="With a Data Template">

...

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

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 ver un ejemplo de introducción, vea Introducción al ejemplo Data Templating.

Estilos

Los estilos permiten a los programadores y diseñadores normalizar un aspecto determinado de sus productos. WPF proporciona un modelo de estilo sólido, que es la base del 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.

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

...

<!-- Data template is specified by the ItemTemplate attribute -->

<ListBox

ItemsSource="{Binding}"

ItemTemplate="{StaticResource myTaskTemplate}"

HorizontalContentAlignment="Stretch"

IsSynchronizedWithCurrentItem="True"

Margin="5,0,5,5" />

...

</Window>

XAML Copiar código

<Window

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://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}">

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.

Para obtener más información, vea Aplicar estilos y plantillas. Para ver un ejemplo 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 interfaz de usuario (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.

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

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

XAML Copiar código

<Window

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://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>

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.

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

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. Para ver un ejemplo de introducción, vea Ejemplo Application Resources.

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. Como el aspecto 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). Estos temas 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 con mayor facilidad.

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.

XAML Copiar código

<ResourceDictionary

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

<!-- Define background color resource -->

<SolidColorBrush x:Key="defaultBackground" Color="Red" />

<!-- Define other resources -->

...

</ResourceDictionary>

XAML Copiar código

<Application

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://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>

XAML Copiar código

<!-- Blue Skin -->

<ResourceDictionary

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

xmlns:local="clr-namespace:SDKSample">

<Style TargetType="{x:Type Button}">

<Setter Property="Background" Value="Blue" />

</Style>

...

<!-- Blue Skin -->

<ResourceDictionary

Para obtener más información, vea la sección sobre temas y recursos compartidos en Aplicar estilos y plantillas. Para ver un ejemplo de introducción, vea Ejemplo Skinned Application.

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

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

xmlns:local="clr-namespace:SDKSample">

<Style TargetType="{x:Type Button}">

<Setter Property="Background" Value="Blue" />

</Style>

...

</ResourceDictionary>

...

</ResourceDictionary>

XAML Copiar código

<!-- Yellow Skin -->

<ResourceDictionary

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

xmlns:local="clr-namespace:SDKSample">

<Style TargetType="{x:Type Button}">

<Setter Property="Background" Value="Yellow" />

</Style>

...

<!-- Yellow Skin -->

<ResourceDictionary

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

xmlns:local="clr-namespace:SDKSample">

<Style TargetType="{x:Type Button}">

<Setter Property="Background" Value="Yellow" />

</Style>

...

</ResourceDictionary>

...

</ResourceDictionary>

XAML Copiar código

<UserControl

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

x:Class="SDKSample.NumericUpDown">

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

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

C# Copiar código

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

...

}

}

Visual Basic Copiar código

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

XAML Copiar código

<Window

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

x:Class="SDKSample.UserControlWindow"

xmlns:local="clr-namespace:SDKSample"

Title="User Control Window">

...

Procedimientos recomendados en WPF

Resumen

Introducciones y ejemplos recomendados

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

Para obtener más información sobre controles personalizados, vea Información general sobre la creación de controles. Para ver ejemplos de introducción, vea Ejemplos de personalización de controles.

<!-- Numeric Up/Down user control -->

<local:NumericUpDown />

...

</Window>

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:

� Procedimientos de accesibilidad recomendados

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

� Optimizar WPF: Rendimiento de aplicaciones

� Seguridad de Windows Presentation Foundation

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.

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

Temas de introducción

Ejemplos

Información general sobre gráficos 3D

Procedimientos de accesibilidad recomendados

Información general sobre animaciones

Información general sobre anotaciones

Información general sobre la administración de aplicaciones

Información general sobre comandos

Información general sobre la creación de controles

Información general sobre controles

Información general sobre el enlace de datos

Información general sobre plantillas de datos

Información general sobre las propiedades de dependencia

Documentos en Windows Presentation Foundation

Árboles en WPF

Información general sobre documentos dinámicos

Información general sobre geometría

Introducción a las entradas manuscritas

Información general sobre imágenes

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

Información general sobre formas y dibujo básico en WPF

Tipografía en Windows Presentation Foundation

Seguridad de Windows Presentation Foundation

Información general sobre ventanas de WPF

Información general sobre pinceles de WPF

Modelo de contenido de WPF

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

Información general sobre características de gráficos, animación y multimedia en WPF

Ejemplo 3-D Solids

Ejemplos Accessibility

Ejemplo Animation Example Gallery

Ejemplo Application Resources

Introducción al ejemplo Data Templating

Ejemplo Introduction to Styling and Templating

Ejemplo Media Gallery

Ejemplos de empaquetado

Vea también

Ejemplo Brushes

Ejemplos de personalización de controles

Ejemplos de Control Library

Ejemplo Creating an XPS Document

Demo Data Binding

Ejemplos de entrada manuscrita digital

Ejemplo Document Serialization

Ejemplo FlowDocument Properties

Ejemplo Geometries

Printing an XPS Document

Ejemplo Shape Elements

Información general sobre formas y dibujo básico en WPF

Ejemplo Skinned Application

Ejemplo Styling with ControlTemplates

Ejemplos de tipografía

Ejemplo WPF Layout Gallery

Demo WPF Photo Viewer

Conceptos

Información general sobre Windows Presentation Foundation

Comentarios de la comunidad de Windows Presentation Foundation

Enviar comentarios sobre este tema a Microsoft.

Contraer todo Código: Todos

Biblioteca de clases de .NET Framework

Button (Clase) Miembros Ejemplo Vea también Enviar comentarios

Representa un control de botón de Windows, que reacciona al evento ButtonBase.Click.

Espacio de nombres: System.Windows.Controls Ensamblado: PresentationFramework (en PresentationFramework.dll) XMLNS para XAML: http://schemas.microsoft.com/winfx/xaml/presentation

Sintaxis

Comentarios

Ejemplos

Visual Basic (Declaración)

Public Class Button _

Inherits ButtonBase

Visual Basic (Uso)

Dim instance As Button

C#

public class Button : ButtonBase

Visual C++

public ref class Button : public ButtonBase

J#

public class Button extends ButtonBase

JScript

public class Button extends ButtonBase

Uso de elementos de objeto XAML

<Button>

Content

</Button>

La clase Button hereda directamente de la clase System.Windows.Controls.Primitives.ButtonBase.

Modelo de contenido: El valor de Button es un objeto ContentControl. Su propiedad de contenido es Content. Para obtener más información acerca del modelo de contenido de Button, vea Información general sobre el modelo de contenido de controles.

Administre el evento ButtonBase.Click para responder cuando el usuario hace clic en Button.

El método OnMouseLeftButtonDown marca el evento MouseLeftButtonDown como administrado. Para responder al evento MouseLeftButtonDown, asocie un controlador de eventos al evento PreviewMouseLeftButtonDown o llame a AddHandler(RoutedEvent, Delegate, Boolean) con handledEventsToo establecido en true.

El ejemplo siguiente muestra tres botones que responden a los clics de tres maneras diferentes.

� Desplazar: el primer botón cambia de color cuando el usuario se desplaza con el mouse sobre el botón.

� Presionar: el segundo botón requiere que se presione el mouse mientras el puntero del mouse está

encima del botón.

� Soltar: el tercero no restablece el color de fondo de los botones hasta que se presione el mouse y se suelte el botón.

Más código

XAML Copiar código

<Button Name="btn1" Background="Pink"

BorderBrush="Black" BorderThickness="1"

Click="OnClick1" ClickMode="Hover">

ClickMe1

</Button>

<Button Name="btn2" Background="LightBlue"

BorderBrush="Black" BorderThickness="1"

Click="OnClick2" ClickMode="Press">

ClickMe2

</Button>

<Button Name="btn3"

Click="OnClick3" ClickMode="Release">

Reset

</Button>

C# Copiar código

void OnClick1(object sender, RoutedEventArgs e)

{

btn1.Background = Brushes.LightBlue;

}

void OnClick2(object sender, RoutedEventArgs e)

{

btn2.Background = Brushes.Pink;

}

void OnClick3(object sender, RoutedEventArgs e)

{

btn1.Background = Brushes.Pink;

btn2.Background = Brushes.LightBlue;

}

Visual Basic Copiar código

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

btn1.Background = Brushes.LightBlue

End Sub

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

btn2.Background = Brushes.Pink

End Sub

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

btn1.Background = Brushes.Pink

btn2.Background = Brushes.LightBlue

End Sub

Cómo: Crear un botón que tenga una imagen

En este ejemplo se muestra cómo incluir una imagen en un control Button.

Cómo: Crear un control que tenga tecla de acceso y ajuste de texto

En este ejemplo se muestra cómo crear un control que tiene una tecla de acceso y admite el ajuste de texto. En el ejemplo se utiliza un control Label para ilustrar estos conceptos.

Jerarquía de herencia

Seguridad para subprocesos

Plataformas

Información de versión

Vea también

System.Object System.Windows.Threading.DispatcherObject System.Windows.DependencyObject System.Windows.Media.Visual System.Windows.UIElement System.Windows.FrameworkElement System.Windows.Controls.Control System.Windows.Controls.ContentControl System.Windows.Controls.Primitives.ButtonBase System.Windows.Controls.Button

Todos los miembros static (Shared en Visual Basic) públicos de este tipo son seguros para la ejecución de subprocesos. No se garantiza que los miembros de instancias sean seguros para la ejecución de subprocesos.

Windows Vista

.NET Framework y .NET Compact Framework no admiten todas las versiones de cada plataforma. Para obtener una lista de las versiones compatibles, vea Requisitos de sistema de .NET Framework.

.NET Framework

Compatible con: 3.5, 3.0 SP1, 3.0

Conceptos

Ejemplo WPF Controls Gallery

Button Samples

Información general sobre controles

Biblioteca de controles

Referencia

Button (Miembros)

System.Windows.Controls (Espacio de nombres)

Enviar comentarios sobre este tema a Microsoft.

Contraer todo Código: Todos

Biblioteca de clases de .NET Framework

RepeatButton (Clase) Miembros Ejemplo Vea también Enviar comentarios

Representa un control que provoca su evento Click de forma repetida desde el momento en que se presiona hasta que se suelta.

Espacio de nombres: System.Windows.Controls.Primitives Ensamblado: PresentationFramework (en PresentationFramework.dll) XMLNS para XAML: http://schemas.microsoft.com/winfx/xaml/presentation

Sintaxis

Comentarios

Ejemplos

Visual Basic (Declaración)

Public Class RepeatButton _

Inherits ButtonBase

Visual Basic (Uso)

Dim instance As RepeatButton

C#

public class RepeatButton : ButtonBase

Visual C++

public ref class RepeatButton : public ButtonBase

J#

public class RepeatButton extends ButtonBase

JScript

public class RepeatButton extends ButtonBase

Uso de elementos de objeto XAML

<RepeatButton>

Content

</RepeatButton>

Modelo de contenido: El valor de RepeatButton es un objeto ContentControl. Su propiedad de contenido es Content. Para obtener más información acerca del modelo de contenido de RepeatButton, vea Información general sobre el modelo de contenido de controles.

La clase RepeatButton que representa un control que es similar a Button. Sin embargo, los botones repetidos le proporcionan control sobre cuándo y cómo se produce el evento Click. RepeatButton provoca el evento Click de forma repetida desde el momento en que se presiona hasta que se suelta. La propiedad Delay determina cuándo comienza el evento. También puede controlar el intervalo de las repeticiones con la propiedad Interval.

En el siguiente ejemplo se muestra cómo crear un RepeatButton.

XAML Copiar código

<RepeatButton Width="100" DockPanel.Dock="Top"

Delay="500" Interval="100"

Jerarquía de herencia

Seguridad para subprocesos

Click="Increase">

Increase

</RepeatButton>

<TextBlock Name="valueText"

Width="100" DockPanel.Dock="Top"

TextAlignment="Center" FontSize="16">

0

</TextBlock>

<RepeatButton Width="100" DockPanel.Dock="Top"

Delay="500" Interval="100"

Click="Decrease">

Decrease

</RepeatButton>

C# Copiar código

void Increase(object sender, RoutedEventArgs e)

{

Int32 Num = Convert.ToInt32(valueText.Text);

valueText.Text = ((Num + 1).ToString());

}

void Decrease(object sender, RoutedEventArgs e)

{

Int32 Num = Convert.ToInt32(valueText.Text);

valueText.Text = ((Num - 1).ToString());

}

Visual Basic Copiar código

Sub Increase(ByVal sender As Object, ByVal e As RoutedEventArgs)

Num = CInt(valueText.Text)

valueText.Text = ((Num + 1).ToString())

End Sub

Sub Decrease(ByVal sender As Object, ByVal e As RoutedEventArgs)

Num = CInt(valueText.Text)

valueText.Text = ((Num - 1).ToString())

End Sub

System.Object System.Windows.Threading.DispatcherObject System.Windows.DependencyObject System.Windows.Media.Visual System.Windows.UIElement System.Windows.FrameworkElement System.Windows.Controls.Control System.Windows.Controls.ContentControl System.Windows.Controls.Primitives.ButtonBase System.Windows.Controls.Primitives.RepeatButton

Todos los miembros static (Shared en Visual Basic) públicos de este tipo son seguros para la ejecución de subprocesos. No se garantiza que los miembros de instancias sean seguros para la

Plataformas

Información de versión

Vea también

ejecución de subprocesos.

Windows Vista

.NET Framework y .NET Compact Framework no admiten todas las versiones de cada plataforma. Para obtener una lista de las versiones compatibles, vea Requisitos de sistema de .NET Framework.

.NET Framework

Compatible con: 3.5, 3.0 SP1, 3.0

Referencia

RepeatButton (Miembros)

System.Windows.Controls.Primitives (Espacio de nombres)

Enviar comentarios sobre este tema a Microsoft.

Contraer todo Código: Todos

Biblioteca de clases de .NET Framework

OpenFileDialog (Clase) Miembros Vea también Enviar comentarios

Representa un cuadro de diálogo común que permite al usuario especificar un nombre de archivo para abrir uno o varios archivos.

Espacio de nombres: Microsoft.Win32 Ensamblado: PresentationFramework (en PresentationFramework.dll) XMLNS para XAML: No asignado a un xmlns.

Sintaxis

Jerarquía de herencia

Seguridad para subprocesos

Plataformas

Información de versión

Visual Basic (Declaración)

Public NotInheritable Class OpenFileDialog _

Inherits FileDialog

Visual Basic (Uso)

Dim instance As OpenFileDialog

C#

public sealed class OpenFileDialog : FileDialog

Visual C++

public ref class OpenFileDialog sealed : public FileDialog

J#

public final class OpenFileDialog extends FileDialog

JScript

public final class OpenFileDialog extends FileDialog

Uso de elementos de objeto XAML

<OpenFileDialog .../>

System.Object Microsoft.Win32.CommonDialog Microsoft.Win32.FileDialog Microsoft.Win32.OpenFileDialog

Todos los miembros static (Shared en Visual Basic) públicos de este tipo son seguros para la ejecución de subprocesos. No se garantiza que los miembros de instancias sean seguros para la ejecución de subprocesos.

Windows Vista

.NET Framework y .NET Compact Framework no admiten todas las versiones de cada plataforma. Para obtener una lista de las versiones compatibles, vea Requisitos de sistema de .NET Framework.

Vea también

.NET Framework

Compatible con: 3.5, 3.0 SP1, 3.0

Referencia

OpenFileDialog (Miembros)

Microsoft.Win32 (Espacio de nombres)

Enviar comentarios sobre este tema a Microsoft.

Contraer todo Código: Todos

Biblioteca de clases de .NET Framework

PrintDialog (Clase) Miembros Ejemplo Vea también Enviar comentarios

Invoca un cuadro de diálogo de impresión de Microsoft Windows estándar que configura PrintTicket y PrintQueue según los datos proporcionados por el usuario e imprime luego un documento.

Espacio de nombres: System.Windows.Controls Ensamblado: PresentationFramework (en PresentationFramework.dll) XMLNS para XAML: http://schemas.microsoft.com/winfx/xaml/presentation

Sintaxis

Comentarios

Ejemplos

Visual Basic (Declaración)

Public Class PrintDialog

Visual Basic (Uso)

Dim instance As PrintDialog

C#

public class PrintDialog

Visual C++

public ref class PrintDialog

J#

public class PrintDialog

JScript

public class PrintDialog

Uso de elementos de objeto XAML

<PrintDialog .../>

Un usuario puede utilizar el cuadro de diálogo Imprimir para seleccionar una impresora, configurarla y realizar un trabajo de impresión.

En sentido estricto, puede utilizar el método PrintDocument sin abrir nunca el cuadro de diálogo. En ese sentido, se puede utilizar el control como un componente de impresión oculto. No obstante, por razones de rendimiento, sería mejor utilizar el método AddJob o uno de los numerosos métodos Write y WriteAsync de XpsDocumentWriter. Para obtener más información sobre esto, vea Cómo: Imprimir mediante programación archivos XPS y Printing an XPS Document.

No confunda esta clase, System.Windows.Controls.PrintDialog, con System.Windows.Forms.PrintDialog. Esta última se utiliza con aplicaciones de formularios Windows Forms. System.Windows.Controls.PrintDialog se utiliza con aplicaciones de Windows Presentation Foundation (WPF).

El ejemplo siguiente muestra cómo crear una instancia y mostrar un sencillo PrintDialog mediante marcado y código de Lenguaje de marcado de aplicaciones extensible (XAML).

...

XAML Copiar código

<Button Width="200" Click="InvokePrint">Invoke PrintDialog</Button>

C# Copiar código

public void InvokePrint(object sender, RoutedEventArgs e)

{

// Create the print dialog object and set options

PrintDialog pDialog = new PrintDialog();

pDialog.PageRangeSelection = PageRangeSelection.AllPages;

pDialog.UserPageRangeEnabled = true;

// Display the dialog. This returns true if the user presses the Print button.

Nullable<Boolean> print = pDialog.ShowDialog();

if (print == true)

{

XpsDocument xpsDocument = new XpsDocument("C:\\FixedDocumentSequence.xps", FileAccess.ReadWrite);

FixedDocumentSequence fixedDocSeq = xpsDocument.GetFixedDocumentSequence();

pDialog.PrintDocument(fixedDocSeq.DocumentPaginator, "Test print job");

}

Jerarquía de herencia

Seguridad para subprocesos

Plataformas

Información de versión

Vea también

}

System.Object System.Windows.Controls.PrintDialog

Todos los miembros static (Shared en Visual Basic) públicos de este tipo son seguros para la ejecución de subprocesos. No se garantiza que los miembros de instancias sean seguros para la ejecución de subprocesos.

Windows Vista

.NET Framework y .NET Compact Framework no admiten todas las versiones de cada plataforma. Para obtener una lista de las versiones compatibles, vea Requisitos de sistema de .NET Framework.

.NET Framework

Compatible con: 3.5, 3.0 SP1, 3.0

Conceptos

Información general sobre impresión

Referencia

PrintDialog (Miembros)

System.Windows.Controls (Espacio de nombres)

Enviar comentarios sobre este tema a Microsoft.

Contraer todo Código: Todos

Biblioteca de clases de .NET Framework

SaveFileDialog (Clase) Miembros Vea también Enviar comentarios

Representa un cuadro de diálogo común que permite al usuario especificar un nombre de archivo para guardar un archivo con ese nombre. Una aplicación que se ejecute con confianza parcial no podrá utilizar SaveFileDialog.

Espacio de nombres: Microsoft.Win32 Ensamblado: PresentationFramework (en PresentationFramework.dll) XMLNS para XAML: No asignado a un xmlns.

Sintaxis

Jerarquía de herencia

Seguridad para subprocesos

Plataformas

Información de versión

Visual Basic (Declaración)

Public NotInheritable Class SaveFileDialog _

Inherits FileDialog

Visual Basic (Uso)

Dim instance As SaveFileDialog

C#

public sealed class SaveFileDialog : FileDialog

Visual C++

public ref class SaveFileDialog sealed : public FileDialog

J#

public final class SaveFileDialog extends FileDialog

JScript

public final class SaveFileDialog extends FileDialog

Uso de elementos de objeto XAML

<SaveFileDialog .../>

System.Object Microsoft.Win32.CommonDialog Microsoft.Win32.FileDialog Microsoft.Win32.SaveFileDialog

Todos los miembros static (Shared en Visual Basic) públicos de este tipo son seguros para la ejecución de subprocesos. No se garantiza que los miembros de instancias sean seguros para la ejecución de subprocesos.

Windows Vista

.NET Framework y .NET Compact Framework no admiten todas las versiones de cada plataforma. Para obtener una lista de las versiones compatibles, vea Requisitos de sistema de .NET Framework.

Vea también

.NET Framework

Compatible con: 3.5, 3.0 SP1, 3.0

Referencia

SaveFileDialog (Miembros)

Microsoft.Win32 (Espacio de nombres)

Enviar comentarios sobre este tema a Microsoft.

Contraer todo Código: Todos

Biblioteca de clases de .NET Framework

InkCanvas (Clase) Miembros Ejemplo Vea también Enviar comentarios

Define una área que recibe y muestra trazos de entrada manuscrita.

Espacio de nombres: System.Windows.Controls Ensamblado: PresentationFramework (en PresentationFramework.dll) XMLNS para XAML: http://schemas.microsoft.com/winfx/xaml/presentation

Sintaxis

Comentarios

Visual Basic (Declaración)

<ContentPropertyAttribute("Children")> _

Public Class InkCanvas _

Inherits FrameworkElement _

Implements IAddChild

Visual Basic (Uso)

Dim instance As InkCanvas

C#

[ContentPropertyAttribute("Children")]

public class InkCanvas : FrameworkElement, IAddChild

Visual C++

[ContentPropertyAttribute(L"Children")]

public ref class InkCanvas : public FrameworkElement,

IAddChild

J#

/** @attribute ContentPropertyAttribute("Children") */

public class InkCanvas extends FrameworkElement implements IAddChild

JScript

public class InkCanvas extends FrameworkElement implements IAddChild

Uso de elementos de objeto XAML

<InkCanvas>

Children

</InkCanvas>

InkCanvas es un elemento que se puede utilizar para recibir y mostrar entradas de entrada manuscrita. Normalmente esta operación se lleva a cabo mediante el uso de un lápiz o un mouse que interactúan con un digitalizador para generar trazos de entrada manuscrita. Los trazos creados se representan como objetos Stroke y se pueden manipular mediante programación o a través de los datos proporcionados por el usuario. InkCanvas permite al usuario modificar o eliminar un objeto Stroke existente.

InkCanvas se puede enlazar a un origen de datos. Por ejemplo, puede enlazar la propiedad Strokes a una cadena codificada en base 64 que contenga los datos de entrada manuscrita en el Formato serializado de tinta (ISF) o incluso puede enlazarla a la propiedad Strokes de otra clase InkCanvas. También puede enlazar propiedades, como DefaultDrawingAttributes y EditingMode, a otros orígenes de datos.

Ejemplos

En el ejemplo siguiente se muestra cómo se simula el uso de un lápiz y un marcador de resaltado en la misma clase InkCanvas. En este ejemplo se supone que el elemento raíz del archivo de lenguaje de marcado (XAML) es una clase DockPanel denominada root. También se supone que hay un control

Button denominado switchHighlighter y que los eventos Click y Loaded están conectados al

controlador de eventos del ejemplo.

C# Copiar código

InkCanvas inkCanvas1 = new InkCanvas();

DrawingAttributes inkDA;

DrawingAttributes highlighterDA;

bool useHighlighter = false;

// Add an InkCanvas to the window, and allow the user to

// switch between using a green pen and a purple highlighter

// on the InkCanvas.

private void WindowLoaded(object sender, EventArgs e)

{

inkCanvas1.Background = Brushes.DarkSlateBlue;

inkCanvas1.DefaultDrawingAttributes.Color = Colors.SpringGreen;

root.Children.Add(inkCanvas1);

// Set up the DrawingAttributes for the pen.

inkDA = new DrawingAttributes();

inkDA.Color = Colors.SpringGreen;

inkDA.Height = 5;

inkDA.Width = 5;

inkDA.FitToCurve = false;

// Set up the DrawingAttributes for the highlighter.

highlighterDA = new DrawingAttributes();

highlighterDA.Color = Colors.Orchid;

highlighterDA.IsHighlighter = true;

highlighterDA.IgnorePressure = true;

highlighterDA.StylusTip = StylusTip.Rectangle;

highlighterDA.Height = 30;

highlighterDA.Width = 10;

inkCanvas1.DefaultDrawingAttributes = inkDA;

}

// Create a button called switchHighlighter and use

// SwitchHighlighter_Click to handle the Click event.

// The useHighlighter variable is a boolean that indicates

// whether the InkCanvas renders ink as a highlighter.

// Switch between using the 'pen' DrawingAttributes and the

// 'highlighter' DrawingAttributes.

void SwitchHighlighter_Click(Object sender, RoutedEventArgs e)

{

useHighlighter = !useHighlighter;

if (useHighlighter)

{

switchHighlighter.Content = "Use Pen";

inkCanvas1.DefaultDrawingAttributes = highlighterDA;

}

else

{

switchHighlighter.Content = "Use Highlighter";

inkCanvas1.DefaultDrawingAttributes = inkDA;

}

}

Visual Basic Copiar código

Private WithEvents inkCanvas1 As New InkCanvas()

Private inkDA As DrawingAttributes

Private highlighterDA As DrawingAttributes

Private useHighlighter As Boolean = False

' Add an InkCanvas to the window, and allow the user to

' switch between using a green pen and a purple highlighter

' on the InkCanvas.

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

inkCanvas1.Background = Brushes.DarkSlateBlue

inkCanvas1.DefaultDrawingAttributes.Color = Colors.SpringGreen

' Add the InkCanvas to the DockPanel, named root.

root.Children.Add(inkCanvas1)

' Set up the DrawingAttributes for the pen.

inkDA = New DrawingAttributes()

With inkDA

.Color = Colors.SpringGreen

.Height = 5

.Width = 5

.FitToCurve = True

End With

' Set up the DrawingAttributes for the highlighter.

highlighterDA = New DrawingAttributes()

With highlighterDA

.Color = Colors.Orchid

.IsHighlighter = True

.IgnorePressure = True

.StylusTip = StylusTip.Rectangle

.Height = 30

.Width = 10

End With

inkCanvas1.DefaultDrawingAttributes = inkDA

End Sub 'WindowLoaded

' Create a button called switchHighlighter and use

' SwitchHighlighter_Click to handle the Click event.

' The useHighlighter variable is a boolean that indicates

' whether the InkCanvas renders ink as a highlighter.

' Switch between using the 'pen' DrawingAttributes and the

' 'highlighter' DrawingAttributes when the user clicks on .

Sub SwitchHighlighter_Click(ByVal sender As [Object], ByVal e As RoutedEventArgs)

useHighlighter = Not useHighlighter

If useHighlighter Then

switchHighlighter.Content = "Use Pen"

inkCanvas1.DefaultDrawingAttributes = highlighterDA

Else

switchHighlighter.Content = "Use Highlighter"

inkCanvas1.DefaultDrawingAttributes = inkDA

End If

End Sub 'SwitchHighlighter_Click

En el ejemplo siguiente se declaran dos objetos InkCanvas en XAML y se establece el enlace de datos entre ellos y otros orígenes de datos. El primer control InkCanvas, denominado ic, se enlaza a dos

orígenes de datos. Las propiedades EditingMode y DefaultDrawingAttributes de ic se enlazan a

objetos ListBox, que a su vez se enlazan a las matrices definidas en XAML. Las propiedades EditingMode, DefaultDrawingAttributes y Strokes del segundo objeto InkCanvas están enlazadas al primer objeto InkCanvas en el código siguiente.

XAML Copiar código

<Canvas>

<Canvas.Resources>

<!--Define an array containing the InkEditingMode Values.-->

<x:Array x:Key="MyEditingModes" x:Type="{x:Type InkCanvasEditingMode}">

<x:Static Member="InkCanvasEditingMode.Ink"/>

<x:Static Member="InkCanvasEditingMode.Select"/>

<x:Static Member="InkCanvasEditingMode.EraseByPoint"/>

<x:Static Member="InkCanvasEditingMode.EraseByStroke"/>

</x:Array>

<!--Define an array containing some DrawingAttributes.-->

<x:Array x:Key="MyDrawingAttributes"

x:Type="{x:Type DrawingAttributes}">

<DrawingAttributes Color="Black" FitToCurve="true"

Width="3" Height="3"/>

<DrawingAttributes Color="Blue" FitToCurve="false"

Width="5" Height="5"/>

<DrawingAttributes Color="Red" FitToCurve="true"

Width="7" Height="7"/>

</x:Array>

<!--Create a DataTemplate to display the

DrawingAttributes shown above-->

<DataTemplate DataType="{x:Type DrawingAttributes}" >

<Border Width="80" Height="{Binding Path=Height}">

<Border.Background >

<SolidColorBrush Color="{Binding Path=Color}"/>

</Border.Background>

</Border>

</DataTemplate>

</Canvas.Resources>

<!--Bind the first InkCavas' DefaultDrawingAtributes to a

Listbox, called lbDrawingAttributes, and its EditingMode to

a ListBox called lbEditingMode.-->

<InkCanvas Name="ic" Background="LightGray"

Canvas.Top="0" Canvas.Left="0"

Height="400" Width="200"

DefaultDrawingAttributes="{Binding

ElementName=lbDrawingAttributes, Path=SelectedItem}"

EditingMode=

"{Binding ElementName=lbEditingMode, Path=SelectedItem}"

>

</InkCanvas>

<!--Bind the Strokes, DefaultDrawingAtributes, and, EditingMode properties of

the second InkCavas the first InkCanvas.-->

<InkCanvas Background="LightBlue"

Canvas.Top="0" Canvas.Left="200"

Height="400" Width="200"

Strokes="{Binding ElementName=ic, Path=Strokes}"

DefaultDrawingAttributes="{Binding

ElementName=ic, Path=DefaultDrawingAttributes}"

EditingMode="{Binding ElementName=ic, Path=EditingMode}">

<InkCanvas.LayoutTransform>

Jerarquía de herencia

Seguridad para subprocesos

Plataformas

Información de versión

Vea también

<ScaleTransform ScaleX="-1" ScaleY="1" />

</InkCanvas.LayoutTransform>

</InkCanvas>

<!--Use the array, MyEditingModes, to populate a ListBox-->

<ListBox Name="lbEditingMode"

Canvas.Top="0" Canvas.Left="450"

Height="100" Width="100"

ItemsSource="{StaticResource MyEditingModes}" />

<!--Use the array, MyDrawingAttributes, to populate a ListBox-->

<ListBox Name="lbDrawingAttributes"

Canvas.Top="150" Canvas.Left="450"

Height="100" Width="100"

ItemsSource="{StaticResource MyDrawingAttributes}" />

</Canvas>

System.Object System.Windows.Threading.DispatcherObject System.Windows.DependencyObject System.Windows.Media.Visual System.Windows.UIElement System.Windows.FrameworkElement System.Windows.Controls.InkCanvas

Todos los miembros static (Shared en Visual Basic) públicos de este tipo son seguros para la ejecución de subprocesos. No se garantiza que los miembros de instancias sean seguros para la ejecución de subprocesos.

Windows Vista

.NET Framework y .NET Compact Framework no admiten todas las versiones de cada plataforma. Para obtener una lista de las versiones compatibles, vea Requisitos de sistema de .NET Framework.

.NET Framework

Compatible con: 3.5, 3.0 SP1, 3.0

Conceptos

Ejemplo WPF Controls Gallery

Enlace de datos

Referencia

InkCanvas (Miembros)

System.Windows.Controls (Espacio de nombres)

Enviar comentarios sobre este tema a Microsoft.

Contraer todo Código: Todos

Biblioteca de clases de .NET Framework

InkPresenter (Clase) Miembros Ejemplo Vea también Enviar comentarios

Representa la entrada manuscrita en una superficie.

Espacio de nombres: System.Windows.Controls Ensamblado: PresentationFramework (en PresentationFramework.dll) XMLNS para XAML: http://schemas.microsoft.com/winfx/xaml/presentation

Sintaxis

Comentarios

Ejemplos

Visual Basic (Declaración)

Public Class InkPresenter _

Inherits Decorator

Visual Basic (Uso)

Dim instance As InkPresenter

C#

public class InkPresenter : Decorator

Visual C++

public ref class InkPresenter : public Decorator

J#

public class InkPresenter extends Decorator

JScript

public class InkPresenter extends Decorator

Uso de elementos de objeto XAML

<InkPresenter>

Child

</InkPresenter>

La representación de entrada manuscrita se produce de dos modos: dinámico y estático. La representación dinámica se produce según se escribe la entrada manuscrita en una superficie de escritura a mano: el trazo se representa según se va realizando. La representación estática se produce una vez recopilados los datos del trazo y asociados a un nuevo trazo.

Para representar la entrada manuscrita dinámicamente mediante InkPresenter, asocie la propiedad RootVisual de DynamicRenderer a InkPresenter utilizando el método AttachVisuals. Para representar la entrada manuscrita estáticamente, agregue los objetos del trazo a la propiedad Strokes.

El ejemplo siguiente crea mediante programación un trazo y lo agrega a InkPresenter. En este ejemplo sólo aparece una representación estática, en la que se supone que el evento Loaded está conectado al controlador de eventos, WindowLoaded.

C# Copiar código

public partial class Window1 : Window

{

InkPresenter inkPresenter1;

public Window1()

{

InitializeComponent();

}

private void WindowLoaded(object sender, RoutedEventArgs e)

{

inkPresenter1 = new InkPresenter();

this.Content = inkPresenter1;

StylusPoint segment1Start = new StylusPoint(200, 110);

StylusPoint segment1End = new StylusPoint(185, 150);

StylusPoint segment2Start = new StylusPoint(185, 150);

StylusPoint segment2End = new StylusPoint(135, 150);

StylusPoint segment3Start = new StylusPoint(135, 150);

StylusPoint segment3End = new StylusPoint(175, 180);

StylusPoint segment4Start = new StylusPoint(175, 180);

StylusPoint segment4End = new StylusPoint(160, 220);

StylusPoint segment5Start = new StylusPoint(160, 220);

StylusPoint segment5End = new StylusPoint(200, 195);

StylusPoint segment6Start = new StylusPoint(200, 195);

StylusPoint segment6End = new StylusPoint(240, 220);

StylusPoint segment7Start = new StylusPoint(240, 220);

StylusPoint segment7End = new StylusPoint(225, 180);

StylusPoint segment8Start = new StylusPoint(225, 180);

StylusPoint segment8End = new StylusPoint(265, 150);

StylusPoint segment9Start = new StylusPoint(265, 150);

StylusPoint segment9End = new StylusPoint(215, 150);

StylusPoint segment10Start = new StylusPoint(215, 150);

StylusPoint segment10End = new StylusPoint(200, 110);

StylusPointCollection strokePoints = new StylusPointCollection();

strokePoints.Add(segment1Start);

strokePoints.Add(segment1End);

strokePoints.Add(segment2Start);

strokePoints.Add(segment2End);

strokePoints.Add(segment3Start);

strokePoints.Add(segment3End);

strokePoints.Add(segment4Start);

strokePoints.Add(segment4End);

strokePoints.Add(segment5Start);

strokePoints.Add(segment5End);

strokePoints.Add(segment6Start);

strokePoints.Add(segment6End);

strokePoints.Add(segment7Start);

strokePoints.Add(segment7End);

strokePoints.Add(segment8Start);

strokePoints.Add(segment8End);

strokePoints.Add(segment9Start);

strokePoints.Add(segment9End);

strokePoints.Add(segment10Start);

strokePoints.Add(segment10End);

Stroke newStroke = new Stroke(strokePoints);

inkPresenter1.Strokes.Add(newStroke);

}

}

Visual Basic Copiar código

Class Window1

Inherits Window '

Jerarquía de herencia

Private inkPresenter1 As InkPresenter

Public Sub New()

InitializeComponent()

End Sub 'New

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

inkPresenter1 = New InkPresenter()

Me.Content = inkPresenter1

Dim segment1Start As New StylusPoint(200, 110)

Dim segment1End As New StylusPoint(185, 150)

Dim segment2Start As New StylusPoint(185, 150)

Dim segment2End As New StylusPoint(135, 150)

Dim segment3Start As New StylusPoint(135, 150)

Dim segment3End As New StylusPoint(175, 180)

Dim segment4Start As New StylusPoint(175, 180)

Dim segment4End As New StylusPoint(160, 220)

Dim segment5Start As New StylusPoint(160, 220)

Dim segment5End As New StylusPoint(200, 195)

Dim segment6Start As New StylusPoint(200, 195)

Dim segment6End As New StylusPoint(240, 220)

Dim segment7Start As New StylusPoint(240, 220)

Dim segment7End As New StylusPoint(225, 180)

Dim segment8Start As New StylusPoint(225, 180)

Dim segment8End As New StylusPoint(265, 150)

Dim segment9Start As New StylusPoint(265, 150)

Dim segment9End As New StylusPoint(215, 150)

Dim segment10Start As New StylusPoint(215, 150)

Dim segment10End As New StylusPoint(200, 110)

Dim strokePoints As New StylusPointCollection()

strokePoints.Add(segment1Start)

strokePoints.Add(segment1End)

strokePoints.Add(segment2Start)

strokePoints.Add(segment2End)

strokePoints.Add(segment3Start)

strokePoints.Add(segment3End)

strokePoints.Add(segment4Start)

strokePoints.Add(segment4End)

strokePoints.Add(segment5Start)

strokePoints.Add(segment5End)

strokePoints.Add(segment6Start)

strokePoints.Add(segment6End)

strokePoints.Add(segment7Start)

strokePoints.Add(segment7End)

strokePoints.Add(segment8Start)

strokePoints.Add(segment8End)

strokePoints.Add(segment9Start)

strokePoints.Add(segment9End)

strokePoints.Add(segment10Start)

strokePoints.Add(segment10End)

Dim newStroke As New Stroke(strokePoints)

inkPresenter1.Strokes.Add(newStroke)

End Sub 'WindowLoaded

End Class 'Window1

Seguridad para subprocesos

Plataformas

Información de versión

Vea también

System.Object System.Windows.Threading.DispatcherObject System.Windows.DependencyObject System.Windows.Media.Visual System.Windows.UIElement System.Windows.FrameworkElement System.Windows.Controls.Decorator System.Windows.Controls.InkPresenter

Todos los miembros static (Shared en Visual Basic) públicos de este tipo son seguros para la ejecución de subprocesos. No se garantiza que los miembros de instancias sean seguros para la ejecución de subprocesos.

Windows Vista

.NET Framework y .NET Compact Framework no admiten todas las versiones de cada plataforma. Para obtener una lista de las versiones compatibles, vea Requisitos de sistema de .NET Framework.

.NET Framework

Compatible con: 3.5, 3.0 SP1, 3.0

Referencia

InkPresenter (Miembros)

System.Windows.Controls (Espacio de nombres)

Enviar comentarios sobre este tema a Microsoft.

Contraer todo Código: Todos

Biblioteca de clases de .NET Framework

DocumentViewer (Clase) Miembros Vea también Enviar comentarios

Representa un control de visualización de documentos que puede hospedar contenido FixedDocument paginado como XpsDocument.

Espacio de nombres: System.Windows.Controls Ensamblado: PresentationFramework (en PresentationFramework.dll) XMLNS para XAML: http://schemas.microsoft.com/winfx/xaml/presentation

Sintaxis

Jerarquía de herencia

Seguridad para subprocesos

Plataformas

Visual Basic (Declaración)

<TemplatePartAttribute(Name := "PART_FindToolBarHost", Type := GetType(ContentControl))> _

<TemplatePartAttribute(Name := "PART_ContentHost", Type := GetType(ScrollViewer))> _

Public Class DocumentViewer _

Inherits DocumentViewerBase

Visual Basic (Uso)

Dim instance As DocumentViewer

C#

[TemplatePartAttribute(Name = "PART_FindToolBarHost", Type = typeof(ContentControl))]

[TemplatePartAttribute(Name = "PART_ContentHost", Type = typeof(ScrollViewer))]

public class DocumentViewer : DocumentViewerBase

Visual C++

[TemplatePartAttribute(Name = L"PART_FindToolBarHost", Type = typeof(ContentControl))]

[TemplatePartAttribute(Name = L"PART_ContentHost", Type = typeof(ScrollViewer))]

public ref class DocumentViewer : public DocumentViewerBase

J#

/** @attribute TemplatePartAttribute(Name = "PART_FindToolBarHost", Type = ContentControl) */

/** @attribute TemplatePartAttribute(Name = "PART_ContentHost", Type = ScrollViewer) */

public class DocumentViewer extends DocumentViewerBase

JScript

public class DocumentViewer extends DocumentViewerBase

Uso de elementos de objeto XAML

<DocumentViewer>

Document

</DocumentViewer>

System.Object System.Windows.Threading.DispatcherObject System.Windows.DependencyObject System.Windows.Media.Visual System.Windows.UIElement System.Windows.FrameworkElement System.Windows.Controls.Control System.Windows.Controls.Primitives.DocumentViewerBase System.Windows.Controls.DocumentViewer

Todos los miembros static (Shared en Visual Basic) públicos de este tipo son seguros para la ejecución de subprocesos. No se garantiza que los miembros de instancias sean seguros para la ejecución de subprocesos.

Windows Vista

Información de versión

Vea también

.NET Framework y .NET Compact Framework no admiten todas las versiones de cada plataforma. Para obtener una lista de las versiones compatibles, vea Requisitos de sistema de .NET Framework.

.NET Framework

Compatible con: 3.5, 3.0 SP1, 3.0

Conceptos

Ejemplo WPF Controls Gallery

Referencia

DocumentViewer (Miembros)

System.Windows.Controls (Espacio de nombres)

DocumentPaginator

Enviar comentarios sobre este tema a Microsoft.

Contraer todo Código: Todos

Biblioteca de clases de .NET Framework

FlowDocumentPageViewer (Clase) Miembros Ejemplo Vea también Enviar comentarios

Representa un control para ver el contenido de flujo en un modo de vista fijo que muestra una página de contenido a la vez.

Espacio de nombres: System.Windows.Controls Ensamblado: PresentationFramework (en PresentationFramework.dll) XMLNS para XAML: http://schemas.microsoft.com/winfx/xaml/presentation

Sintaxis

Comentarios

Visual Basic (Declaración)

<TemplatePartAttribute(Name := "PART_FindToolBarHost", Type := GetType(Decorator))> _

Public Class FlowDocumentPageViewer _

Inherits DocumentViewerBase

Visual Basic (Uso)

Dim instance As FlowDocumentPageViewer

C#

[TemplatePartAttribute(Name = "PART_FindToolBarHost", Type = typeof(Decorator))]

public class FlowDocumentPageViewer : DocumentViewerBase

Visual C++

[TemplatePartAttribute(Name = L"PART_FindToolBarHost", Type = typeof(Decorator))]

public ref class FlowDocumentPageViewer : public DocumentViewerBase

J#

/** @attribute TemplatePartAttribute(Name = "PART_FindToolBarHost", Type = Decorator) */

public class FlowDocumentPageViewer extends DocumentViewerBase

JScript

public class FlowDocumentPageViewer extends DocumentViewerBase

Uso de elementos de objeto XAML

<FlowDocumentPageViewer>

Document

</FlowDocumentPageViewer>

Modelo de contenido: FlowDocumentPageViewer sólo permite un objeto FlowDocument como elemento secundario.

FlowDocumentPageViewer muestra el contenido en el modo de vista de una página a la vez. Un control similar, FlowDocumentScrollViewer, muestra el contenido en modo de desplazamiento continuo. Tanto FlowDocumentPageViewer como FlowDocumentScrollViewer son fijos para un modo de vista concreto. Por otro lado, FlowDocumentReader incluye características que permiten al usuario elegir dinámicamente entre varios modos de vista (suministrados por la enumeración FlowDocumentReaderViewingMode), a costa de que el rendimiento sea más pobre que el de FlowDocumentPageViewer o FlowDocumentScrollViewer.

En la ilustración siguiente se muestra un control FlowDocumentPageViewer con su interfaz de usuario (UI) predeterminada.

Ejemplos

� Área de contenido: el área de contenido muestra el contenido del objeto FlowDocument especificado por la propiedad Document.

� Barra de herramientas: la barra de herramientas predeterminada se acopla bajo el área de contenido y hospeda controles para navegar por las páginas y cambiar el nivel de zoom.

� Controles de navegación de páginas: los controles de navegación de páginas incluyen un botón que permite saltar a la página siguiente (flecha abajo) o a la página anterior (flecha arriba), así como los indicadores del número de página actual y el número total de páginas.

� Controles de zoom: los controles de zoom permiten al usuario aumentar o reducir el nivel de zoom haciendo clic en los botones con el signo más y el signo menos, respectivamente. Los controles de zoom incluyen también un control deslizante para ajustar el nivel de zoom. Para obtener más información, vea Zoom.

� Búsqueda: el usuario puede utilizar el método abreviado de teclado Ctrl+F o el método Find para alternar un cuadro de texto de búsqueda que permita buscar cadenas en el contenido. Para obtener más información, vea Find.

En el ejemplo siguiente se define el objeto FlowDocumentPageViewer representado en la figura anterior.

XAML Copiar código

<FlowDocumentPageViewer Margin="10" BorderBrush="Black" BorderThickness="1">

<FlowDocument

ColumnWidth="400"

IsOptimalParagraphEnabled="True" IsHyphenationEnabled="True"

>

<Section FontSize="12">

<Paragraph>

<Bold>Neptune</Bold> (planet), major planet in the solar system, eighth planet

from the Sun and fourth largest in diameter. Neptune maintains an almost constant

distance, about 4,490 million km (about 2,790 million mi), from the Sun. Neptune

revolves outside the orbit of Uranus and for most of its orbit moves inside the

elliptical path of the outermost planet Pluto (see Solar System). Every 248 years,

Pluto’s elliptical orbit brings the planet inside Neptune’s nearly circular orbit

for about 20 years, temporarily making Neptune the farthest planet from the Sun.

The last time Pluto’s orbit brought it inside Neptune’s orbit was in 1979. In

1999 Pluto’s orbit carried it back outside Neptune’s orbit.

<Figure

Width="140" Height="50" Background="GhostWhite"

HorizontalAnchor="PageLeft"

HorizontalOffset="100" VerticalOffset="20"

>

<Paragraph

FontStyle="Italic" TextAlignment="Left"

Background="Beige" Foreground="DarkGreen"

>

Neptune has 72 times Earth's volume...

</Paragraph>

</Figure>

<Floater

Background="GhostWhite"

Width="285" HorizontalAlignment="Left"

>

<Table CellSpacing="5">

<Table.Columns>

<TableColumn Width="155"/>

<TableColumn Width="130"/>

</Table.Columns>

<TableRowGroup>

<TableRow>

<TableCell ColumnSpan="3">

<Paragraph>Neptune Stats</Paragraph>

</TableCell>

</TableRow>

<TableRow Background="LightGoldenrodYellow" FontSize="12">

<TableCell>

<Paragraph FontWeight="Bold">Mean Distance from Sun</Paragraph>

</TableCell>

<TableCell>

<Paragraph>4,504,000,000 km</Paragraph>

</TableCell>

</TableRow>

<TableRow FontSize="12" Background="LightGray">

<TableCell>

<Paragraph FontWeight="Bold">Mean Diameter</Paragraph>

</TableCell>

<TableCell>

<Paragraph>49,532 km</Paragraph>

</TableCell>

</TableRow>

<TableRow Background="LightGoldenrodYellow" FontSize="12">

<TableCell>

<Paragraph FontWeight="Bold">Approximate Mass</Paragraph>

</TableCell>

<TableCell>

<Paragraph>1.0247e26 kg</Paragraph>

</TableCell>

</TableRow>

<TableRow>

<TableCell ColumnSpan="4">

<Paragraph FontSize="10" FontStyle="Italic">

Information from the

<Hyperlink

NavigateUri="http://encarta.msn.com/encnet/refpages/artcenter.aspx"

>Encarta</Hyperlink>

web site.

</Paragraph>

</TableCell>

</TableRow>

</TableRowGroup>

</Table>

</Floater>

</Paragraph>

<Paragraph>

Astronomers believe Neptune has an inner rocky core that is surrounded by a vast

ocean of water mixed with rocky material. From the inner core, this ocean extends

upward until it meets a gaseous atmosphere of hydrogen, helium, and trace amounts

of methane. Neptune has four rings and 11 known moons. Even though Neptune's volume

is 72 times Earth’s volume, its mass is only 17.15 times Earth’s mass. Because of

its size, scientists classify Neptune—along with Jupiter, Saturn, and Uranus—as

one of the giant or Jovian planets (so-called because they resemble Jupiter).

Jerarquía de herencia

Seguridad para subprocesos

Plataformas

Información de versión

Vea también

</Paragraph>

<Paragraph>

<Figure

Width="140" Height="50"

Background="GhostWhite" TextAlignment="Left"

HorizontalAnchor="PageCenter" WrapDirection="Both"

>

<Paragraph FontStyle="Italic" Background="Beige" Foreground="DarkGreen" >

Neptune has an orbital period of ~20 years...

</Paragraph>

</Figure>

Mathematical theories of astronomy led to the discovery of Neptune. To account for

wobbles in the orbit of the planet Uranus, British astronomer John Couch Adams and

French astronomer Urbain Jean Joseph Leverrier independently calculated the existence

and position of a new planet in 1845 and 1846, respectively. They theorized that the

gravitational attraction of this planet for Uranus was causing the wobbles in Uranus’s

orbit. Using information from Leverrier, German astronomer Johann Gottfried Galle first

observed the planet in 1846.

</Paragraph>

</Section>

</FlowDocument>

</FlowDocumentPageViewer>

System.Object System.Windows.Threading.DispatcherObject System.Windows.DependencyObject System.Windows.Media.Visual System.Windows.UIElement System.Windows.FrameworkElement System.Windows.Controls.Control System.Windows.Controls.Primitives.DocumentViewerBase System.Windows.Controls.FlowDocumentPageViewer

Todos los miembros static (Shared en Visual Basic) públicos de este tipo son seguros para la ejecución de subprocesos. No se garantiza que los miembros de instancias sean seguros para la ejecución de subprocesos.

Windows Vista

.NET Framework y .NET Compact Framework no admiten todas las versiones de cada plataforma. Para obtener una lista de las versiones compatibles, vea Requisitos de sistema de .NET Framework.

.NET Framework Compatible con: 3.5, 3.0 SP1, 3.0

Conceptos

Información general sobre documentos dinámicos

Referencia

FlowDocumentPageViewer (Miembros)

System.Windows.Controls (Espacio de nombres)

Enviar comentarios sobre este tema a Microsoft.

Contraer todo Código: Todos

Biblioteca de clases de .NET Framework

FlowDocumentReader (Clase) Miembros Ejemplo Vea también Enviar comentarios

Proporciona un control para ver el contenido dinámico, con compatibilidad integrada para varios modos de vista.

Espacio de nombres: System.Windows.Controls Ensamblado: PresentationFramework (en PresentationFramework.dll) XMLNS para XAML: http://schemas.microsoft.com/winfx/xaml/presentation

Sintaxis

Comentarios

Visual Basic (Declaración)

<ContentPropertyAttribute("Document")> _

<TemplatePartAttribute(Name := "PART_ContentHost", Type := GetType(Decorator))> _

<TemplatePartAttribute(Name := "PART_FindToolBarHost", Type := GetType(Decorator))> _

Public Class FlowDocumentReader _

Inherits Control _

Implements IAddChild

Visual Basic (Uso)

Dim instance As FlowDocumentReader

C#

[ContentPropertyAttribute("Document")]

[TemplatePartAttribute(Name = "PART_ContentHost", Type = typeof(Decorator))]

[TemplatePartAttribute(Name = "PART_FindToolBarHost", Type = typeof(Decorator))]

public class FlowDocumentReader : Control, IAddChild

Visual C++

[ContentPropertyAttribute(L"Document")]

[TemplatePartAttribute(Name = L"PART_ContentHost", Type = typeof(Decorator))]

[TemplatePartAttribute(Name = L"PART_FindToolBarHost", Type = typeof(Decorator))]

public ref class FlowDocumentReader : public Control,

IAddChild

J#

/** @attribute ContentPropertyAttribute("Document") */

/** @attribute TemplatePartAttribute(Name = "PART_ContentHost", Type = Decorator) */

/** @attribute TemplatePartAttribute(Name = "PART_FindToolBarHost", Type = Decorator) */

public class FlowDocumentReader extends Control implements IAddChild

JScript

public class FlowDocumentReader extends Control implements IAddChild

Uso de elementos de objeto XAML

<FlowDocumentReader>

Document

</FlowDocumentReader>

FlowDocumentReader dispone de características que permiten al usuario elegir dinámicamente entre distintos modos de vista, incluido el modo de vista de página única (una página cada vez), dos páginas a la vez (formato de lectura de libro) y desplazamiento continuo (sin límite). Si no necesita cambiar dinámicamente entre diferentes modos de vista, hay visores de contenido dinámico más ligeros que disponen de un modo de vista determinado. FlowDocumentPageViewer muestra el contenido dinámico en una sola página, mientras que FlowDocumentScrollViewer muestra el contenido dinámico en modo de desplazamiento continuo. Para obtener más información sobre los modos de presentación disponibles, vea FlowDocumentReaderViewingMode.

En la ilustración siguiente se muestra un control FlowDocumentReader con su interfaz de usuario (UI) predeterminada.

Ejemplos

� Área de contenido: en el área de contenido se muestra el contenido del objeto FlowDocument especificado por la propiedad Document.

� Barra de herramientas: la barra de herramientas predeterminada se acopla debajo del área de contenido. Tiene controles que permiten buscar contenido, navegar por las páginas, seleccionar un modo de vista y cambiar el nivel de zoom.

� Botón Buscar: el botón Buscar abre el cuadro de diálogo Buscar, que permite al usuario buscar determinados términos o frases en el contenido de FlowDocumentReader. El botón Buscar no se muestra si IsFindEnabled es false. Para obtener más información, vea Find.

� Controles de navegación de páginas: los controles de navegación de páginas incluyen un botón que permite saltar a la página siguiente (flecha abajo) o a la página anterior (flecha arriba), así como los indicadores del número de página actual y el número total de páginas.

� Botones de modos de vista: los botones de modos de vista permiten al usuario seleccionar entre los modos de vista disponibles. Para obtener más información, vea ViewingMode.

� Controles de zoom: los controles de zoom permiten al usuario aumentar o reducir el nivel de zoom haciendo clic en los botones con el signo más y el signo menos, respectivamente. Los controles de zoom incluyen también un control deslizante que permite ajustar el nivel de zoom. Para obtener más información, vea Zoom.

La interfaz de usuario de la barra de herramientas predeterminada no incluye el botón Imprimir.

FlowDocument es el único elemento secundario permitido para FlowDocumentReader. Un elemento FlowDocumentReader no puede hospedar más que un objeto FlowDocument.

En el ejemplo siguiente se define el objeto FlowDocumentReader que se muestra en la ilustración anterior.

XAML Copiar código

<FlowDocumentReader>

<FlowDocument

ColumnWidth="400"

IsOptimalParagraphEnabled="True" IsHyphenationEnabled="True"

>

<Section FontSize="12">

<Paragraph>

<Bold>Neptune</Bold> (planet), major planet in the solar system, eighth planet

from the Sun and fourth largest in diameter. Neptune maintains an almost constant

distance, about 4,490 million km (about 2,790 million mi), from the Sun. Neptune

revolves outside the orbit of Uranus and for most of its orbit moves inside the

elliptical path of the outermost planet Pluto (see Solar System). Every 248 years,

Pluto’s elliptical orbit brings the planet inside Neptune’s nearly circular orbit

for about 20 years, temporarily making Neptune the farthest planet from the Sun.

The last time Pluto’s orbit brought it inside Neptune’s orbit was in 1979. In

1999 Pluto’s orbit carried it back outside Neptune’s orbit.

<!-- This Figure uses relative measurements for width and height. -->

<Figure

Width="0.25" Height="0.1" Background="GhostWhite"

HorizontalAnchor="PageLeft"

HorizontalOffset="100" VerticalOffset="20"

>

<Paragraph

FontStyle="Italic" TextAlignment="Left"

Background="Beige" Foreground="DarkGreen"

>

Neptune has 72 times Earth's volume...

</Paragraph>

</Figure>

<!-- This Floater uses relative measurements for width. -->

<Floater

Background="GhostWhite"

Width="0.4" HorizontalAlignment="Left"

>

<Table CellSpacing="5">

<Table.Columns>

<TableColumn Width="155"/>

<TableColumn Width="130"/>

</Table.Columns>

<TableRowGroup>

<TableRow>

<TableCell ColumnSpan="3">

<Paragraph>Neptune Stats</Paragraph>

</TableCell>

</TableRow>

<TableRow Background="LightGoldenrodYellow" FontSize="12">

<TableCell>

<Paragraph FontWeight="Bold">Mean Distance from Sun</Paragraph>

</TableCell>

<TableCell>

<Paragraph>4,504,000,000 km</Paragraph>

</TableCell>

</TableRow>

<TableRow FontSize="12" Background="LightGray">

<TableCell>

<Paragraph FontWeight="Bold">Mean Diameter</Paragraph>

</TableCell>

<TableCell>

<Paragraph>49,532 km</Paragraph>

</TableCell>

</TableRow>

<TableRow Background="LightGoldenrodYellow" FontSize="12">

<TableCell>

<Paragraph FontWeight="Bold">Approximate Mass</Paragraph>

</TableCell>

<TableCell>

<Paragraph>1.0247e26 kg</Paragraph>

</TableCell>

</TableRow>

<TableRow>

<TableCell ColumnSpan="4">

Jerarquía de herencia

Seguridad para subprocesos

Plataformas

Información de versión

<Paragraph FontSize="10" FontStyle="Italic">

Information from the

<Hyperlink

NavigateUri="http://encarta.msn.com/encnet/refpages/artcenter.aspx"

>Encarta</Hyperlink>

web site.

</Paragraph>

</TableCell>

</TableRow>

</TableRowGroup>

</Table>

</Floater>

</Paragraph>

<Paragraph>

Astronomers believe Neptune has an inner rocky core that is surrounded by a vast

ocean of water mixed with rocky material. From the inner core, this ocean extends

upward until it meets a gaseous atmosphere of hydrogen, helium, and trace amounts

of methane. Neptune has four rings and 11 known moons. Even though Neptune's volume

is 72 times Earth’s volume, its mass is only 17.15 times Earth’s mass. Because of

its size, scientists classify Neptune—along with Jupiter, Saturn, and Uranus—as

one of the giant or Jovian planets (so-called because they resemble Jupiter).

</Paragraph>

<Paragraph>

<Figure

Width="140" Height="50"

Background="GhostWhite" TextAlignment="Left"

HorizontalAnchor="PageCenter" WrapDirection="Both"

>

<Paragraph FontStyle="Italic" Background="Beige" Foreground="DarkGreen" >

Neptune has an orbital period of ~20 years...

</Paragraph>

</Figure>

Mathematical theories of astronomy led to the discovery of Neptune. To account for

wobbles in the orbit of the planet Uranus, British astronomer John Couch Adams and

French astronomer Urbain Jean Joseph Leverrier independently calculated the existence

and position of a new planet in 1845 and 1846, respectively. They theorized that the

gravitational attraction of this planet for Uranus was causing the wobbles in Uranus’s

orbit. Using information from Leverrier, German astronomer Johann Gottfried Galle first

observed the planet in 1846.

</Paragraph>

</Section>

</FlowDocument>

</FlowDocumentReader>

System.Object System.Windows.Threading.DispatcherObject System.Windows.DependencyObject System.Windows.Media.Visual System.Windows.UIElement System.Windows.FrameworkElement System.Windows.Controls.Control System.Windows.Controls.FlowDocumentReader

Todos los miembros static (Shared en Visual Basic) públicos de este tipo son seguros para la ejecución de subprocesos. No se garantiza que los miembros de instancias sean seguros para la ejecución de subprocesos.

Windows Vista

.NET Framework y .NET Compact Framework no admiten todas las versiones de cada plataforma. Para obtener una lista de las versiones compatibles, vea Requisitos de sistema de .NET Framework.

.NET Framework Compatible con: 3.5, 3.0 SP1, 3.0

Vea también

Conceptos

Información general sobre documentos dinámicos

Ejemplos de FlowDocumentReader

Referencia

FlowDocumentReader (Miembros)

System.Windows.Controls (Espacio de nombres)

Enviar comentarios sobre este tema a Microsoft.

Contraer todo Código: Todos

Biblioteca de clases de .NET Framework

FlowDocumentScrollViewer (Clase) Miembros Ejemplo Vea también Enviar comentarios

Proporciona un control para ver contenido dinámico en un modo de desplazamiento continuo.

Espacio de nombres: System.Windows.Controls Ensamblado: PresentationFramework (en PresentationFramework.dll) XMLNS para XAML: http://schemas.microsoft.com/winfx/xaml/presentation

Sintaxis

Comentarios

Visual Basic (Declaración)

<TemplatePartAttribute(Name := "PART_FindToolBarHost", Type := GetType(Decorator))> _

<ContentPropertyAttribute("Document")> _

<TemplatePartAttribute(Name := "PART_ContentHost", Type := GetType(ScrollViewer))> _

<TemplatePartAttribute(Name := "PART_ToolBarHost", Type := GetType(Decorator))> _

Public Class FlowDocumentScrollViewer _

Inherits Control _

Implements IAddChild, IServiceProvider

Visual Basic (Uso)

Dim instance As FlowDocumentScrollViewer

C#

[TemplatePartAttribute(Name = "PART_FindToolBarHost", Type = typeof(Decorator))]

[ContentPropertyAttribute("Document")]

[TemplatePartAttribute(Name = "PART_ContentHost", Type = typeof(ScrollViewer))]

[TemplatePartAttribute(Name = "PART_ToolBarHost", Type = typeof(Decorator))]

public class FlowDocumentScrollViewer : Control, IAddChild,

IServiceProvider

Visual C++

[TemplatePartAttribute(Name = L"PART_FindToolBarHost", Type = typeof(Decorator))]

[ContentPropertyAttribute(L"Document")]

[TemplatePartAttribute(Name = L"PART_ContentHost", Type = typeof(ScrollViewer))]

[TemplatePartAttribute(Name = L"PART_ToolBarHost", Type = typeof(Decorator))]

public ref class FlowDocumentScrollViewer : public Control,

IAddChild, IServiceProvider

J#

/** @attribute TemplatePartAttribute(Name = "PART_FindToolBarHost", Type = Decorator) */

/** @attribute ContentPropertyAttribute("Document") */

/** @attribute TemplatePartAttribute(Name = "PART_ContentHost", Type = ScrollViewer) */

/** @attribute TemplatePartAttribute(Name = "PART_ToolBarHost", Type = Decorator) */

public class FlowDocumentScrollViewer extends Control implements IAddChild,

IServiceProvider

JScript

public class FlowDocumentScrollViewer extends Control implements IAddChild, IServiceProvider

Uso de elementos de objeto XAML

<FlowDocumentScrollViewer>

Document

</FlowDocumentScrollViewer>

FlowDocumentScrollViewer muestra contenido en el modo de desplazamiento continuo. Un control similar, FlowDocumentPageViewer, muestra contenido en el modo de vista de una página a la vez. Tanto FlowDocumentPageViewer como FlowDocumentScrollViewer son fijos para un modo de vista concreto. Por otro lado, FlowDocumentReader incluye características que permiten al usuario elegir dinámicamente entre varios modos de vista (suministrados por la enumeración FlowDocumentReaderViewingMode), a costa de ser más pesado que FlowDocumentPageViewer o FlowDocumentScrollViewer.

En la ilustración siguiente se muestra un control FlowDocumentScrollViewer con su interfaz de usuario (UI) predeterminada.

Ejemplos

De forma predeterminada, se muestra siempre una barra de desplazamiento vertical y una barra de desplazamiento horizontal se vuelve visible si es necesario. La interfaz de usuario predeterminada para FlowDocumentScrollViewer no incluye barra de herramientas; sin embargo, se puede utilizar la propiedad IsToolBarVisible para habilitar una barra de herramientas integrada.

FlowDocument es el único elemento secundario permitido para FlowDocumentScrollViewer. Un elemento FlowDocumentScrollViewer no puede alojar más de un objeto FlowDocument.

En el ejemplo siguiente se define el objeto FlowDocumentScrollViewer representado en la figura anterior.

XAML Copiar código

<FlowDocumentScrollViewer Margin="10" BorderBrush="Black" BorderThickness="1">

<FlowDocument

ColumnWidth="400"

IsOptimalParagraphEnabled="True" IsHyphenationEnabled="True"

>

<Section FontSize="12">

<Paragraph>

<Bold>Neptune</Bold> (planet), major planet in the solar system, eighth planet

from the Sun and fourth largest in diameter. Neptune maintains an almost constant

distance, about 4,490 million km (about 2,790 million mi), from the Sun. Neptune

revolves outside the orbit of Uranus and for most of its orbit moves inside the

elliptical path of the outermost planet Pluto (see Solar System). Every 248 years,

Pluto’s elliptical orbit brings the planet inside Neptune’s nearly circular orbit

for about 20 years, temporarily making Neptune the farthest planet from the Sun.

The last time Pluto’s orbit brought it inside Neptune’s orbit was in 1979. In

1999 Pluto’s orbit carried it back outside Neptune’s orbit.

<Figure

Width="140" Height="50" Background="GhostWhite"

HorizontalAnchor="PageLeft"

HorizontalOffset="100" VerticalOffset="20"

>

<Paragraph

FontStyle="Italic" TextAlignment="Left"

Background="Beige" Foreground="DarkGreen"

>

Neptune has 72 times Earth's volume...

</Paragraph>

</Figure>

<Floater

Background="GhostWhite"

Width="285" HorizontalAlignment="Left"

>

<Table CellSpacing="5">

<Table.Columns>

<TableColumn Width="155"/>

<TableColumn Width="130"/>

</Table.Columns>

<TableRowGroup>

<TableRow>

<TableCell ColumnSpan="3">

<Paragraph>Neptune Stats</Paragraph>

</TableCell>

</TableRow>

<TableRow Background="LightGoldenrodYellow" FontSize="12">

<TableCell>

<Paragraph FontWeight="Bold">Mean Distance from Sun</Paragraph>

</TableCell>

<TableCell>

<Paragraph>4,504,000,000 km</Paragraph>

</TableCell>

</TableRow>

<TableRow FontSize="12" Background="LightGray">

<TableCell>

<Paragraph FontWeight="Bold">Mean Diameter</Paragraph>

</TableCell>

<TableCell>

<Paragraph>49,532 km</Paragraph>

</TableCell>

</TableRow>

<TableRow Background="LightGoldenrodYellow" FontSize="12">

<TableCell>

<Paragraph FontWeight="Bold">Approximate Mass</Paragraph>

</TableCell>

<TableCell>

<Paragraph>1.0247e26 kg</Paragraph>

</TableCell>

</TableRow>

<TableRow>

<TableCell ColumnSpan="4">

<Paragraph FontSize="10" FontStyle="Italic">

Information from the

<Hyperlink

NavigateUri="http://encarta.msn.com/encnet/refpages/artcenter.aspx"

>Encarta</Hyperlink>

web site.

</Paragraph>

</TableCell>

</TableRow>

</TableRowGroup>

</Table>

</Floater>

</Paragraph>

<Paragraph>

Astronomers believe Neptune has an inner rocky core that is surrounded by a vast

ocean of water mixed with rocky material. From the inner core, this ocean extends

upward until it meets a gaseous atmosphere of hydrogen, helium, and trace amounts

of methane. Neptune has four rings and 11 known moons. Even though Neptune's volume

is 72 times Earth’s volume, its mass is only 17.15 times Earth’s mass. Because of

its size, scientists classify Neptune—along with Jupiter, Saturn, and Uranus—as

one of the giant or Jovian planets (so-called because they resemble Jupiter).

</Paragraph>

<Paragraph>

<Figure

Width="140" Height="50"

Background="GhostWhite" TextAlignment="Left"

HorizontalAnchor="PageCenter" WrapDirection="Both"

>

<Paragraph FontStyle="Italic" Background="Beige" Foreground="DarkGreen" >

Neptune has an orbital period of ~20 years...

</Paragraph>

</Figure>

Jerarquía de herencia

Seguridad para subprocesos

Plataformas

Información de versión

Vea también

Mathematical theories of astronomy led to the discovery of Neptune. To account for

wobbles in the orbit of the planet Uranus, British astronomer John Couch Adams and

French astronomer Urbain Jean Joseph Leverrier independently calculated the existence

and position of a new planet in 1845 and 1846, respectively. They theorized that the

gravitational attraction of this planet for Uranus was causing the wobbles in Uranus’s

orbit. Using information from Leverrier, German astronomer Johann Gottfried Galle first

observed the planet in 1846.

</Paragraph>

</Section>

</FlowDocument>

</FlowDocumentScrollViewer>

System.Object System.Windows.Threading.DispatcherObject System.Windows.DependencyObject System.Windows.Media.Visual System.Windows.UIElement System.Windows.FrameworkElement System.Windows.Controls.Control System.Windows.Controls.FlowDocumentScrollViewer

Todos los miembros static (Shared en Visual Basic) públicos de este tipo son seguros para la ejecución de subprocesos. No se garantiza que los miembros de instancias sean seguros para la ejecución de subprocesos.

Windows Vista

.NET Framework y .NET Compact Framework no admiten todas las versiones de cada plataforma. Para obtener una lista de las versiones compatibles, vea Requisitos de sistema de .NET Framework.

.NET Framework

Compatible con: 3.5, 3.0 SP1, 3.0

Conceptos

Información general sobre documentos dinámicos

Referencia

FlowDocumentScrollViewer (Miembros)

System.Windows.Controls (Espacio de nombres)

Enviar comentarios sobre este tema a Microsoft.

Contraer todo Código: Todos

Biblioteca de clases de .NET Framework

StickyNoteControl (Clase) Miembros Ejemplo Vea también Enviar comentarios

Representa un control que permite que los usuarios asocien a los documentos anotaciones escritas a mano o texto escrito a máquina.

Espacio de nombres: System.Windows.Controls Ensamblado: PresentationFramework (en PresentationFramework.dll)

Sintaxis

Visual Basic (Declaración)

<TemplatePartAttribute(Name := "PART_EraseMenuItem", Type := GetType(MenuItem))> _

<TemplatePartAttribute(Name := "PART_SelectMenuItem", Type := GetType(MenuItem))> _

<TemplatePartAttribute(Name := "PART_CloseButton", Type := GetType(Button))> _

<TemplatePartAttribute(Name := "PART_TitleThumb", Type := GetType(Thumb))> _

<TemplatePartAttribute(Name := "PART_ResizeBottomRightThumb", Type := GetType(Thumb))> _

<TemplatePartAttribute(Name := "PART_ContentControl", Type := GetType(ContentControl))> _

<TemplatePartAttribute(Name := "PART_IconButton", Type := GetType(Button))> _

<TemplatePartAttribute(Name := "PART_CopyMenuItem", Type := GetType(MenuItem))> _

<TemplatePartAttribute(Name := "PART_PasteMenuItem", Type := GetType(MenuItem))> _

<TemplatePartAttribute(Name := "PART_InkMenuItem", Type := GetType(MenuItem))> _

Public NotInheritable Class StickyNoteControl _

Inherits Control

Visual Basic (Uso)

Dim instance As StickyNoteControl

C#

[TemplatePartAttribute(Name = "PART_EraseMenuItem", Type = typeof(MenuItem))]

[TemplatePartAttribute(Name = "PART_SelectMenuItem", Type = typeof(MenuItem))]

[TemplatePartAttribute(Name = "PART_CloseButton", Type = typeof(Button))]

[TemplatePartAttribute(Name = "PART_TitleThumb", Type = typeof(Thumb))]

[TemplatePartAttribute(Name = "PART_ResizeBottomRightThumb", Type = typeof(Thumb))]

[TemplatePartAttribute(Name = "PART_ContentControl", Type = typeof(ContentControl))]

[TemplatePartAttribute(Name = "PART_IconButton", Type = typeof(Button))]

[TemplatePartAttribute(Name = "PART_CopyMenuItem", Type = typeof(MenuItem))]

[TemplatePartAttribute(Name = "PART_PasteMenuItem", Type = typeof(MenuItem))]

[TemplatePartAttribute(Name = "PART_InkMenuItem", Type = typeof(MenuItem))]

public sealed class StickyNoteControl : Control

Visual C++

[TemplatePartAttribute(Name = L"PART_EraseMenuItem", Type = typeof(MenuItem))]

[TemplatePartAttribute(Name = L"PART_SelectMenuItem", Type = typeof(MenuItem))]

[TemplatePartAttribute(Name = L"PART_CloseButton", Type = typeof(Button))]

[TemplatePartAttribute(Name = L"PART_TitleThumb", Type = typeof(Thumb))]

[TemplatePartAttribute(Name = L"PART_ResizeBottomRightThumb", Type = typeof(Thumb))]

[TemplatePartAttribute(Name = L"PART_ContentControl", Type = typeof(ContentControl))]

[TemplatePartAttribute(Name = L"PART_IconButton", Type = typeof(Button))]

[TemplatePartAttribute(Name = L"PART_CopyMenuItem", Type = typeof(MenuItem))]

[TemplatePartAttribute(Name = L"PART_PasteMenuItem", Type = typeof(MenuItem))]

[TemplatePartAttribute(Name = L"PART_InkMenuItem", Type = typeof(MenuItem))]

public ref class StickyNoteControl sealed : public Control

J#

/** @attribute TemplatePartAttribute(Name = "PART_EraseMenuItem", Type = MenuItem) */

/** @attribute TemplatePartAttribute(Name = "PART_SelectMenuItem", Type = MenuItem) */

/** @attribute TemplatePartAttribute(Name = "PART_CloseButton", Type = Button) */

/** @attribute TemplatePartAttribute(Name = "PART_TitleThumb", Type = Thumb) */

/** @attribute TemplatePartAttribute(Name = "PART_ResizeBottomRightThumb", Type = Thumb) */

/** @attribute TemplatePartAttribute(Name = "PART_ContentControl", Type = ContentControl) */

/** @attribute TemplatePartAttribute(Name = "PART_IconButton", Type = Button) */

/** @attribute TemplatePartAttribute(Name = "PART_CopyMenuItem", Type = MenuItem) */

/** @attribute TemplatePartAttribute(Name = "PART_PasteMenuItem", Type = MenuItem) */

/** @attribute TemplatePartAttribute(Name = "PART_InkMenuItem", Type = MenuItem) */

public final class StickyNoteControl extends Control

Comentarios

Ejemplos

JScript

public final class StickyNoteControl extends Control

XAML

No se puede crear una instancia de esta clase directamente en XAML.

Una nota rápida proporciona una área rectangular cuyo contenido es independiente del texto, imagen u otro material donde se encuentre delimitada la nota.

La clase StickyNoteControl y sus miembros son públicos, de modo que se le puede asignar un estilo, pero no se trata de un constructor público. Las instancias se crean con CreateTextStickyNoteCommand y CreateInkStickyNoteCommand de la clase AnnotationService.

Cuando se crea una nota rápida, se designa como uno de estos dos tipos:

� Las notas rápidas de texto tienen una área de contenido RichTextBox en la que se puede escribir y que se puede editar como cualquier otra área de texto enriquecido. Los usuarios pueden escribir en ella, así como cortar, copiar y pegar tanto dentro de la nota como entre la nota y otras aplicaciones. También pueden pegarse imágenes en la nota. Los métodos abreviados de teclado de texto enriquecido normales también se encuentran disponibles.

� Las notas rápidas manuscritas tienen una área de contenido InkCanvas que puede editarse como cualquier otro lienzo de entrada manuscrita. Por ejemplo, pueden borrarse trazos. Con un Tablet PC u otro hardware adecuado, los usuarios pueden escribir notas a mano.

La interfaz de usuario (UI) de StickyNoteControl hace que se convierta en una forma más eficaz de anotar material que añadir marcas a una impresión o utilizar notas físicas escritas a mano. También resulta más flexible que simplemente agregar o tachar el texto de un documento.

� Es posible cambiar el tamaño de las notas rápidas.

� Las notas rápidas pueden minimizarse en un icono y expandirse.

� Una nota rápida, cuando se maximiza, puede arrastrarse hasta una nueva posición en una ventana sin necesidad de cambiar la ubicación de su delimitador.

� El contenido exacto al que se aplica una nota rápida se resalta y incluye entre corchetes.

� Es posible aplicar dos o más notas rápidas al mismo contenido o a contenido superpuesto.

� Si se produce algún cambio en el contenido del documento en el que está delimitada nota rápida, la nota rápida pasa a una posición relativa al contenido al que estaba enlazada.

� En el caso de las notas rápidas de texto, las líneas ajustarán automáticamente. Si se modifica el tamaño de la nota, las líneas volverán a ajustarse en función de las necesidades. Si el contenido se extiende por debajo de la parte inferior de la nota, aparecerá una barra de desplazamiento vertical.

� En el caso de las notas rápidas manuscritas, aparecerán barras de desplazamiento verticales y horizontales siempre que el contenido se extienda más allá de los límites de la nota.

En el ejemplo siguiente se muestra cómo pueden configurarse los comandos de menú de DocumentViewer para ejecutar CreateTextStickyNoteCommand y CreateInkStickyNoteCommand de la clase AnnotationService. Encontrará el ejemplo completo en Ejemplo DocumentViewer with Annotations XPS-Store. En el ejemplo se muestra cómo leer un documento de XML Paper Specification (XPS) en un control DocumentViewer y, a continuación, cómo habilitar la compatibilidad necesaria para agregar notas rápidas creadas por usuario.

XAML Copiar código

<DocumentViewer.ContextMenu>

<ContextMenu>

<MenuItem Command="ApplicationCommands.Copy" />

<Separator />

<!-- Add a Highlight annotation to a user selection. -->

<MenuItem Command="ann:AnnotationService.CreateHighlightCommand"

Header="Add Highlight" />

<!-- Add a Text Note annotation to a user selection. -->

<MenuItem Command="ann:AnnotationService.CreateTextStickyNoteCommand"

Header="Add Text Note" />

<!-- Add an Ink Note annotation to a user selection. -->

<MenuItem Command="ann:AnnotationService.CreateInkStickyNoteCommand"

Header="Add Ink Note" />

<Separator />

<!-- Remove Highlights from a user selection. -->

Jerarquía de herencia

Seguridad para subprocesos

Plataformas

Información de versión

Vea también

<MenuItem Command="ann:AnnotationService.ClearHighlightsCommand"

Header="Remove Highlights" />

<!-- Remove Text Notes and Ink Notes from a user selection. -->

<MenuItem Command="ann:AnnotationService.DeleteStickyNotesCommand"

Header="Remove Notes" />

<!-- Remove Highlights, Text Notes, Ink Notes from a selection. -->

<MenuItem Command="ann:AnnotationService.DeleteAnnotationsCommand"

Header="Remove Highlights &amp; Notes" />

</ContextMenu>

</DocumentViewer.ContextMenu>

System.Object System.Windows.Threading.DispatcherObject System.Windows.DependencyObject System.Windows.Media.Visual System.Windows.UIElement System.Windows.FrameworkElement System.Windows.Controls.Control System.Windows.Controls.StickyNoteControl

Todos los miembros static (Shared en Visual Basic) públicos de este tipo son seguros para la ejecución de subprocesos. No se garantiza que los miembros de instancias sean seguros para la ejecución de subprocesos.

Windows Vista

.NET Framework y .NET Compact Framework no admiten todas las versiones de cada plataforma. Para obtener una lista de las versiones compatibles, vea Requisitos de sistema de .NET Framework.

.NET Framework

Compatible con: 3.5, 3.0 SP1, 3.0

Conceptos

Información general sobre anotaciones

Referencia

StickyNoteControl (Miembros)

System.Windows.Controls (Espacio de nombres)

AnnotationService

Enviar comentarios sobre este tema a Microsoft.

Contraer todo Código: Todos

Windows Presentation Foundation

Información general sobre recursosVea también Enviar comentarios

En esta introducción se describe el uso de los recursos de WPF como una manera simple de reutilizar los objetos y valores que se definen de forma común. Esta introducción se centra en cómo utilizar los recursos en XAML. También se pueden crear y obtener acceso a los recursos utilizando código o, de forma intercambiable, código y Lenguaje de marcado de aplicaciones extensible (XAML). Para obtener más información, vea Recursos y código.

Este tema contiene las secciones siguientes.

� Utilizar recursos en XAML

� Recursos estáticos y recursos dinámicos

� Estilos, plantillas de datos y claves implícitas

� Temas relacionados

Utilizar recursos en XAML

En el ejemplo siguiente se define un objeto SolidColorBrush como un recurso en el elemento raíz de una página. A continuación, el ejemplo hace referencia al recurso y lo utiliza para establecer las propiedades de varios elementos secundarios, incluyendo un objeto Ellipse, un objeto TextBlock y un objeto Button.

Cada elemento del marco de trabajo (FrameworkElement o FrameworkContentElement) tiene una propiedad Resources, que es la que contiene los recursos (como un objeto ResourceDictionary) definidos por un recurso. Los recursos se pueden definir en cualquier elemento. Sin embargo, normalmente se definen en el elemento raíz que, en el ejemplo, es Page.

Cada recurso incluido en un diccionario de recursos debe tener una clave única. Al definir los recursos en el marcado, se asigna la clave única a través de x:Key (atributo). Normalmente, la clave es una cadena; sin embargo, también se puede establecer en objetos de otros tipos utilizando las extensiones de marcado adecuadas. Las claves de recursos que no son de cadena se utilizan en ciertas áreas de características en WPF, principalmente en los estilos, los recursos de componentes y los estilos de datos.

Una vez definido un recurso, se puede hacer referencia al recurso que se debe utilizar para un valor de propiedad utilizando una sintaxis de extensión de marcado de recursos que especifique el nombre de la clave, como por ejemplo:

En el ejemplo anterior, cuando el cargador XAML procesa el valor {StaticResource MyBrush} para la propiedad Background de

Button, la lógica de búsqueda de recursos comprueba primero la existencia del elemento Button en el diccionario de recursos. Si Button

XAML

<Page Name="root"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

>

<Page.Resources>

<SolidColorBrush x:Key="MyBrush" Color="Gold"/>

<Style TargetType="Border" x:Key="PageBackground">

<Setter Property="Background" Value="Blue"/>

</Style>

<Style TargetType="TextBlock" x:Key="TitleText">

<Setter Property="Background" Value="Blue"/>

<Setter Property="DockPanel.Dock" Value="Top"/>

<Setter Property="FontSize" Value="18"/>

<Setter Property="Foreground" Value="#4E87D4"/>

<Setter Property="FontFamily" Value="Trebuchet MS"/>

<Setter Property="Margin" Value="0,40,10,10"/>

</Style>

<Style TargetType="TextBlock" x:Key="Label">

<Setter Property="DockPanel.Dock" Value="Right"/>

<Setter Property="FontSize" Value="8"/>

<Setter Property="Foreground" Value="{StaticResource MyBrush}"/>

<Setter Property="FontFamily" Value="Arial"/>

<Setter Property="FontWeight" Value="Bold"/>

<Setter Property="Margin" Value="0,3,10,0"/>

</Style>

</Page.Resources>

<StackPanel>

<Border Style="{StaticResource PageBackground}">

<DockPanel>

<TextBlock Style="{StaticResource TitleText}">Title</TextBlock>

<TextBlock Style="{StaticResource Label}">Label</TextBlock>

<TextBlock DockPanel.Dock="Top" HorizontalAlignment="Left" FontSize="36" Foreground="{StaticResource MyBrush}" Text="Text" Margin="20" />

<Button DockPanel.Dock="Top" HorizontalAlignment="Left" Height="30" Background="{StaticResource MyBrush}" Margin="40">Button</Button>

<Ellipse DockPanel.Dock="Top" HorizontalAlignment="Left" Width="100" Height="100" Fill="{StaticResource MyBrush}" Margin="40" />

</DockPanel>

</Border>

</StackPanel>

</Page>

XAML Copiar código

<Button Background="{StaticResource MyBrush}"/>

<Ellipse Fill="{StaticResource MyBrush}"/>

Recursos estáticos y recursos dinámicos

no tiene una definición de la clave de recurso MyBrush (no la tiene; su colección de recursos está vacía), la búsqueda comprueba a

continuación el elemento primario de Button, que es Page. Así, cuando se define un recurso en el elemento raíz Page, todos los elementos del árbol lógico del objeto Page pueden tener acceso a él y se puede reutilizar el mismo recurso para establecer el valor de cualquier propiedad que acepte el objeto Type que representa el recurso. En el ejemplo anterior, el mismo recurso MyBrush establece

dos propiedades diferentes: la propiedad Background de un objeto Button y la propiedad Fill de un objeto Rectangle.

Se puede hacer referencia a un recurso como un recurso estático o como un recurso dinámico. Para ello, se utilizan las extensiones de marcado Extensión de marcado StaticResource o Extensión de marcado DynamicResource. Una extensión de marcado es una característica de XAML que permite especificar una referencia de objeto y que procesa la cadena del atributo y devuelve el objeto a un cargador XAML. Para obtener más información sobre el comportamiento de la extensión de marcado, vea Extensiones de marcado y XAML.

Cuando se utiliza una extensión de marcado, normalmente se proporcionan uno o varios parámetros en forma de cadena que son procesados por dicha extensión de marcado, en lugar de evaluarse en el contexto de la propiedad que se está estableciendo. Extensión de marcado StaticResource procesa una clave buscando el valor para dicha clave en todos los diccionarios de recursos disponibles. Esto sucede durante la carga, que es el momento en el que el proceso de carga necesita asignar el valor de la propiedad que acepta la referencia de recurso estático. Extensión de marcado DynamicResource, por el contrario, procesa una clave creando una expresión, y dicha expresión permanece sin evaluar hasta que se ejecuta la aplicación, momento en el cual se evalúa y proporciona un valor.

Al hacer referencia a un recurso, las consideraciones siguientes pueden influir a la hora de decidir si se va a utilizar una referencia de recurso estático o una referencia de recurso dinámico:

� El diseño general utilizado para crear los recursos para la aplicación (por página, en la aplicación, en XAML separado, en un ensamblado sólo para recursos).

� La funcionalidad de la aplicación: ¿la actualización de recursos en tiempo real forma parte de los requisitos de la aplicación?

� El comportamiento de búsqueda respectivo de ese tipo de referencia de recurso.

� El tipo concreto de recurso o de propiedad, así como el comportamiento nativo de esos tipos.

Recursos estáticos

Las referencias de recursos estáticos funcionan mejor en las circunstancias siguientes:

� No tiene ninguna intención de cambiar el valor del recurso una vez que ha hecho referencia a él por primera vez.

� El diseño de la aplicación concentra la mayoría de sus recursos en diccionarios de recursos en el nivel de aplicación o de página. Las referencias de recursos estáticos no se vuelven a evaluar basándose en los comportamientos en tiempo de ejecución, como recargar una página, por lo que puede haber cierta mejora en el rendimiento si se evita el uso de grandes cantidades de referencias de recursos dinámicos cuando no son necesarias para el diseño de los recursos y de la aplicación.

� Está estableciendo el valor de una propiedad que no está en un objeto DependencyObject o Freezable.

� Está creando un diccionario de recursos que se compilará en una DLL y que se empaquetará como parte de la aplicación o se compartirá entre distintas aplicaciones.

� Está creando un tema para un control personalizado y está definiendo recursos que se utilizan dentro de los temas. En este caso, no es conveniente utilizar el comportamiento de búsqueda de referencia de recursos dinámicos, sino el comportamiento de referencia de recursos estáticos con objeto de que la búsqueda sea predecible y se circunscriba al tema. Con una referencia de recursos dinámicos, incluso una referencia dentro de un tema permanecerá sin evaluar hasta el tiempo de ejecución, y existe la posibilidad de que cuando se aplique el tema, algún elemento local redefina una clave a la que el tema está intentando hacer referencia, con lo que dicho elemento se encontrará antes que el propio tema durante la búsqueda. Si este es el caso, el tema no se comportará de la manera esperada.

� Está utilizando los recursos para establecer un gran número de propiedades de dependencia. Las propiedades de dependencia permiten el almacenamiento en caché del valor efectivo tal y como ha sido habilitado por el sistema de propiedades, por lo que si se proporciona un valor para una propiedad de dependencia que se puede evaluar en el momento de la carga, dicha propiedad no tendrá que comprobar la existencia de una expresión que se ha vuelto a evaluar y podrá devolver el último valor efectivo. Esta técnica puede suponer una mejora en el rendimiento.

Comportamiento de la búsqueda de recursos estáticos

1. El proceso de búsqueda comprueba la presencia de la clave solicitada dentro del diccionario de recursos definido por el elemento que establece la propiedad.

2. A continuación, el proceso de búsqueda recorre en sentido ascendente el árbol lógico, hacia el elemento primario y su diccionario de recursos. Este proceso continúa hasta que se alcanza el elemento raíz.

3. Por último, se comprueban los recursos de la aplicación. Los recursos de la aplicación son los existentes dentro del diccionario de recursos definido por el objeto Application para la aplicación de WPF.

Las referencias de recursos estáticos desde un diccionario de recursos deben hacer referencia a un recurso que haya sido definido léxicamente con anterioridad. Las referencias adelantadas no se pueden resolver mediante una referencia de recurso estático. Por este motivo, si utiliza referencias de recursos estáticos, debe diseñar la estructura de los diccionarios de recursos de tal forma que los recursos pensados para su uso individual se definan en o cerca del principio de los respectivos diccionarios.

La búsqueda de recursos estáticos se puede ampliar a los temas, o a los recursos del sistema, pero esto sólo se admite porque el cargador XAML aplaza la solicitud. Este aplazamiento es necesario para que el tema en tiempo de ejecución en el momento cargar la página se aplique correctamente a la aplicación. Sin embargo, no se recomienda el uso de referencias de recursos estáticos a claves que sólo existen en temas o como recursos del sistema. Esto se debe a que dichas referencias no se vuelven a evaluar si el usuario cambia el tema en tiempo real. Las referencias de recursos dinámicos son más confiables cuando se solicitan recursos del tema o del sistema. La excepción se produce cuando el propio elemento del tema solicita otro recurso. Por las razones mencionadas anteriormente, estas referencias deberían ser referencias de recursos estáticos.

El comportamiento de excepción varía si no se encuentra una referencia de recurso estático. Si se aplazase el recurso, la excepción se produciría en tiempo de ejecución. Si no se aplazase el recurso, la excepción se produciría en el momento de la carga.

Recursos dinámicos

Los recursos dinámicos funcionan mejor en las circunstancias siguientes:

� El valor del recurso depende de condiciones que no se conocen hasta el tiempo de ejecución. Esto incluye los recursos del sistema, o los recursos que de otra forma serían establecidos por el usuario. Por ejemplo, puede crear valores de establecedor que hacen

Estilos, plantillas de datos y claves implícitas

referencia a las propiedades del sistema, de la forma expuesta por SystemColors, SystemFonts o SystemParameters. Estos valores son auténticamente dinámicos porque proceden del entorno en tiempo de ejecución del usuario y del sistema operativo. También es posible tener temas de nivel de aplicación que pueden cambiar, en los que el acceso a recursos de nivel de página también debe capturar los cambios.

� Está creando o haciendo referencia a los estilos del tema para un control personalizado.

� Desea ajustar el contenido de un objeto ResourceDictionary durante la duración de una aplicación.

� Dispone de una estructura de recursos compleja que tiene interdependencias, y en la que es posible que se necesite una referencia adelantada. A diferencia de las referencias de recursos estáticos, las referencias de recursos dinámicos admiten las referencias adelantadas, ya que no es necesario evaluar el recurso hasta el tiempo de ejecución y, por consiguiente, las referencias adelantadas no son un concepto pertinente.

� Está haciendo referencia a un recurso que es de gran tamaño desde la perspectiva de un espacio de compilación o de trabajo, y es posible que dicho recurso no se utilice inmediatamente al cargar la página. Las referencias de recursos estáticos siempre se cargan desde XAML al cargar la página; sin embargo, una referencia de un recurso dinámico no lo hace hasta que se utiliza realmente.

� Está creando un estilo cuyos valores de establecedor podrían proceder de otros valores influenciados por los temas o por otras configuraciones del usuario.

� Está aplicando recursos a elementos que podrían haber cambiado de elemento primario en el árbol lógico durante la duración de la aplicación. Al cambiar el elemento primario, también se cambia potencialmente el ámbito de búsqueda de recursos, por lo que si desea que el recurso para un elemento que ha cambiado de elemento primario se vuelva a evaluar dependiendo del nuevo ámbito, siempre debe utilizar una referencia de recurso dinámico.

Comportamiento de la búsqueda de recursos dinámicos

El comportamiento de búsqueda de recursos para una referencia de recurso dinámico es similar al comportamiento de búsqueda establecido en el código si se llama a FindResource o a SetResourceReference.

1. El proceso de búsqueda comprueba la presencia de la clave solicitada dentro del diccionario de recursos definido por el elemento que establece la propiedad.

� Si el elemento define una propiedad Style, se comprueba el diccionario Resources dentro de Style.

� Si el elemento define una propiedad Template, se comprueba el diccionario Resources dentro de FrameworkTemplate.

2. A continuación, el proceso de búsqueda recorre en sentido ascendente el árbol lógico, hacia el elemento primario y su diccionario de recursos. Este proceso continúa hasta que se alcanza el elemento raíz.

3. Por último, se comprueban los recursos de la aplicación. Los recursos de la aplicación son los existentes dentro del diccionario de recursos definido por el objeto Application para la aplicación de WPF.

4. Se comprueba la existencia del tema activo actualmente en el diccionario de recursos de temas. Si el tema cambia en tiempo de ejecución, se vuelve a evaluar el valor.

5. Se comprueban los recursos del sistema.

El comportamiento de excepción (si existe) varía:

� Si una llamada a FindResource solicita un recurso, y éste no se encuentra, se inicia una excepción.

� Si una llamada a TryFindResource solicita un recurso, y éste no se encuentra, no se inicia ninguna excepción, pero el valor devuelto es null. Si la propiedad que se establece no acepta null, todavía es posible que se inicie un excepción más profunda (esto depende de la propiedad individual que se esté estableciendo).

� Si una referencia de recurso dinámico solicitara un recurso en XAML, y éste no se encontrara, el comportamiento dependerá del sistema general de propiedades, pero el comportamiento general es como si no se hubiera producido ninguna operación de configuración de propiedades en el nivel en el que existe el recurso. Por ejemplo, si intenta establecer el fondo de un elemento de botón individual utilizando un recurso que no se ha podido evaluar, no se devuelve ningún conjunto de valores, pero el valor efectivo todavía puede proceder de otros participantes en el sistema de propiedades y en la prioridad de valores. Por ejemplo, el valor del fondo todavía podría proceder de un estilo de botón definido localmente o del estilo del tema. Para las propiedades que no se definen en los estilos de tema, el valor efectivo después de una evaluación de recursos con errores podría proceder del valor predeterminado en los metadatos de la propiedad.

Restricciones

Las referencias de recursos dinámicos tienen algunas restricciones importantes. Al menos debe cumplirse una de las condiciones siguientes:

� La propiedad que se establece debe ser una propiedad en un objeto FrameworkElement o FrameworkContentElement. Dicha propiedad debe estar respaldada por un objeto DependencyProperty.

� La referencia es para un valor dentro de un objeto Style Setter.

� La propiedad que se establece debe ser una propiedad en un objeto Freezable que se proporciona como un valor para una propiedad de FrameworkElement o FrameworkContentElement, o un valor Setter.

Dado que la propiedad que se establece debe ser una propiedad de DependencyProperty o Freezable, la mayoría de los cambios en la propiedad se pueden propagar a la interfaz de usuario debido a que dichos cambios (el valor de recurso dinámico modificado) están confirmados por el sistema de propiedades. La mayoría de los controles incluyen lógica que forzará otro diseño del control si cambia un objeto DependencyProperty y esa propiedad podría afectar al diseño. Sin embargo, no está garantizado que todas las propiedades que tengan una Extensión de marcado DynamicResource como valor proporcionen éste de manera que se actualicen en tiempo real en la interfaz de usuario. Esa funcionalidad podría variar dependiendo de la propiedad, así como del tipo que posea ésta o incluso de la estructura lógica de la aplicación.

Anteriormente, se ha dicho que todos los elementos de un objeto ResourceDictionary deben tener una clave. Sin embargo, eso no significa que todos los recursos deben tener un atributo x:Key explícito. Varios tipos de objetos admiten una clave implícita cuando se definen como un recurso, donde el valor de la clave está asociado al valor de otra propiedad. Esto se conoce como una clave implícita, mientras que un atributo x:Key es una clave explícita. Se puede sobrescribir cualquier clave implícita especificando una clave explícita.

Un escenario muy importante para los recursos es el obtenido al definir un objeto Style. De hecho, Style se define casi siempre como una entrada en un diccionario de recursos, ya que los estilos están pensados intrínsecamente para su reutilización. Para obtener más información acerca de los estilos, vea Aplicar estilos y plantillas.

Los estilos para los controles se pueden crear con una clave implícita; así mismo, también se puede hacer referencia a ellos mediante

Vea también

dicha clave. Los estilos del tema que definen la apariencia predeterminada de un control se basan en esta clave implícita. La clave implícita desde el punto de vista de la solicitud es el objeto Type del propio control. La clave implícita desde el punto de vista de la definición del recurso es la propiedad TargetType del estilo. Por consiguiente, si está creando temas para controles personalizados, al crear estilos que interactúan con estilos de tema existentes no necesita especificar un x:Key (atributo) para ese objeto Style. Y si desea utilizar los estilos con tema, no es necesario que especifique ningún estilo. Por ejemplo, la definición de estilo siguiente funciona, aunque el recurso Style no parece tener una clave:

En realidad, el estilo tiene una clave: la clave implícita typeof(Button). En el marcado, puede especificar directamente una propiedad TargetType como nombre del tipo (o también puede utilizar {x:Type...} para devolver un objeto Type.

A través de los mecanismos de estilo del tema predeterminado utilizados por WPF, ese estilo se aplica como el estilo en tiempo de ejecución de un objeto Button en la página, aunque el propio objeto Button no intenta especificar su propiedad Style o una referencia de recurso concreta al estilo. El estilo definido en la página se encontrará antes que el estilo de diccionario de tema en la secuencia de búsqueda, utilizando la misma clave que este último estilo. También podría especificar <Button>Hello</Button> en cualquier lugar de

la página, y el estilo definido con la propiedad TargetType de Button se aplicaría a ese botón. Si lo desea, también puede asignar

explícitamente al estilo el mismo valor de tipo que TargetType, por motivos de claridad en el marcado, pero eso es opcional.

Las claves implícitas para los estilos no se aplican en un control si OverridesDefaultStyle es true (observe también que OverridesDefaultStyle se podría establecer como parte del comportamiento nativo para la clase de control, en lugar de establecerse explícitamente en una instancia del control). Asimismo, para poder admitir las claves implícitas para los escenarios de clase derivada, el control debe invalidar DefaultStyleKey (todos los controles existentes proporcionados como parte de WPF hacen esto). Para obtener más información sobre el diseño de estilos, temas y controles, vea Instrucciones para el diseño de controles con estilos.

DataTemplate también tiene una clave implícita. La clave implícita para un objeto DataTemplate es el valor de la propiedad DataType. DataType también se puede especificar como el nombre del tipo en lugar de hacerlo explícitamente utilizando {x:Type...}. Para obtener información detallada, vea Información general sobre plantillas de datos.

XAML Copiar código

<Style TargetType="Button">

<Setter Property="Background">

<Setter.Value>

<LinearGradientBrush>

<GradientStop Offset="0.0" Color="AliceBlue"/>

<GradientStop Offset="1.0" Color="Salmon"/>

</LinearGradientBrush>

</Setter.Value>

</Setter>

<Setter Property="FontSize" Value="18"/>

</Style>

Conceptos

Optimizar el rendimiento: Recursos de aplicación

Recursos y código

Cómo: Definir y hacer referencia a un recurso

Información general sobre la administración de aplicaciones

Extensión de marcado x:Type

Extensión de marcado StaticResource

Extensión de marcado DynamicResource

Referencia

ResourceDictionary

Enviar comentarios sobre este tema a Microsoft.

Contraer todo Código: Todos

Windows Presentation Foundation

Información general sobre animacionesVea también Enviar comentarios

Windows Presentation Foundation (WPF) proporciona un conjunto eficaz de características de gráficos y diseño que permite crear interfaces de usuario y documentos atractivos. Las animaciones pueden hacer que una interfaz de usuario sea más vistosa y práctica. Simplemente con animar un color de fondo o con aplicar un elemento Transform animado, puede crear transiciones de pantalla espectaculares o proporcionar indicaciones visuales útiles.

Aquí se ofrece una introducción al sistema de animación y temporización de WPF. Se centra en la animación de objetos WPF mediante guiones gráficos.

Este tema contiene las secciones siguientes.

Introducción a las animaciones

Sistema de animación de propiedades de WPF

Ejemplo: Hacer que un elemento se intensifique y se atenúe hasta desaparecer

Una animación es una ilusión que se crea mediante el cambio rápido entre una serie de imágenes, cada una de las cuales es ligeramente diferente de la anterior. El cerebro percibe el grupo de imágenes como una sola escena cambiante. En las películas, esta efecto se obtiene mediante el uso de cámaras que graban muchas fotografías, o fotogramas, cada segundo. Cuando los fotogramas se reproducen en un proyector, la audiencia ve una imagen en movimiento.

La animación en un equipo es similar. Por ejemplo, un programa que hace que un dibujo de un rectángulo se desvanezca hasta desaparecer de la vista podría funcionar de la siguiente manera.

� El programa crea un temporizador.

� El programa comprueba el temporizador en los intervalos establecidos para ver cuánto tiempo ha transcurrido.

� Cada vez que el programa comprueba el temporizador, calcula el valor de opacidad actual del rectángulo en función del tiempo que ha transcurrido.

� Después, el programa actualiza el rectángulo con el nuevo valor y lo redibuja.

Antes de WPF, los programadores de Microsoft Windows tenían que crear y administrar sus propios sistemas de control de tiempo o utilizar bibliotecas personalizadas especiales. WPF incluye un sistema del control de tiempo eficaz que se expone a través del código administrado y Lenguaje de marcado de aplicaciones extensible (XAML), y que está completamente integrado en el marco de trabajo de WPF. La animación de WPF permite animar controles y otros objetos gráficos de forma sencilla.

WPF controla todo el trabajo de administración del sistema de temporización y de actualización de la pantalla que se produce en segundo plano. Proporciona clases de control de tiempo que permiten centrarse en los efectos que se desean crear, en lugar de en la manera de lograr esos efectos. WPF también permite crear fácilmente animaciones propias exponiendo clases base de animación de las que pueden heredar sus propias clases para generar animaciones personalizadas. Estas animaciones personalizadas se benefician de la mayoría de las ventajas de rendimiento de las clases de animación estándar.

Si conoce algunos conceptos importantes del sistema de temporización, le resultará más fácil usar las animaciones de WPF. Lo más importante es que, en WPF, los objetos se animan al aplicar animaciones a sus propiedades individuales. Por ejemplo, para hacer que un elemento de marco crezca, se animan sus propiedades Width y Height. Para hacer que un objeto se desvanezca hasta desaparecer de la vista, se anima su propiedad Opacity.

Para tener funcionalidad de animación, una propiedad debe cumplir los tres requisitos siguientes:

� Debe ser una propiedad de dependencia.

� Debe pertenecer a una clase que herede de DependencyObject e implemente la interfaz IAnimatable.

� Debe haber un tipo de animación compatible disponible. Si Windows Presentation Foundation (WPF) no proporciona ninguno, puede crear el suyo propio. Consulte Información general sobre animaciones personalizadas.

WPF contiene muchos objetos con propiedades que se pueden animar. Algunos controles, como Button y TabControl, y también los objetos Panel y Shape heredan de DependencyObject. La mayoría de sus propiedades son propiedades de dependencia.

Las animaciones pueden usarse casi en cualquier parte, lo que incluye estilos y plantillas de control. Las animaciones no tienen que ser visuales; puede animar objetos que no formen parte de la interfaz de usuario siempre y cuando cumplan los criterios que se describen en esta sección.

En este ejemplo se muestra cómo usar una animación de WPF para animar el valor de una propiedad de dependencia. Se usa DoubleAnimation, que es un tipo de animación que genera valores Double, para animar la propiedad Opacity de un elemento Rectangle. Como resultado, Rectangle se intensifica y se atenúa hasta desaparecer de la vista.

En la primera parte del ejemplo se crea un elemento Rectangle y se muestra en un objeto Page. Los pasos siguientes muestran cómo crear una animación y aplicarla a la propiedad Opacity del rectángulo.

Copiar código

<Page

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

WindowTitle="Fading Rectangle Example">

<StackPanel Margin="10">

<Rectangle

Name="MyRectangle"

Width="100"

Height="100"

Fill="Blue">

</Rectangle>

</StackPanel>

Parte 1: Crear una DoubleAnimation

Una manera de conseguir que un elemento se intensifique y se atenúe hasta desaparecer es animar su propiedad Opacity. Dado que la propiedad Opacity es de tipo Double, necesita una animación que genere valores double. DoubleAnimation es una animación que se ajusta a ese perfil. DoubleAnimation crea una transición entre dos valores double. Para especificar el valor inicial, establezca su propiedad From. Para especificar el valor final, establezca su propiedad To.

1. Un valor de opacidad de 1.0 hace que el objeto sea completamente opaco y un valor de opacidad de 0.0 hace que sea

completamente invisible. Para lograr una transición de la animación de 1.0 a 0.0, establezca su propiedad From en 1.0 y su

propiedad To en 0.0.

[C#]

2. Luego debe especificar un valor Duration. El valor Duration de una animación especifica cuánto tiempo le lleva pasar del valor de origen al valor de destino. En el ejemplo siguiente, se proporciona a la animación una duración de cinco segundos.

3. En el código anterior se mostraba una animación que cambiaba de 1.0 a 0.0, lo que hacía que el elemento de destino se atenuara y

pasase de ser completamente opaco a ser completamente invisible. Para hacer que el elemento vuelva a intensificarse antes de desaparecer, establezca la propiedad AutoReverse de la animación en true. Para hacer que la animación se repita indefinidamente, establezca su propiedad RepeatBehavior en Forever.

Parte 2: Crear un guión gráfico

Para aplicar una animación a un objeto, se crea un objeto Storyboard y se usan las propiedades asociadas TargetName y TargetProperty para especificar el objeto y la propiedad que se desean animar.

1. Cree Storyboard y agregue la animación como su elemento secundario.

</Page>

Copiar código

using System;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Shapes;

using System.Windows.Media;

using System.Windows.Media.Animation;

namespace Microsoft.SDK.Animation

{

public class RectangleOpacityFadeExample : Page

{

public RectangleOpacityFadeExample()

{

NameScope.SetNameScope(this, new NameScope());

this.WindowTitle = "Fading Rectangle Example";

StackPanel myPanel = new StackPanel();

myPanel.Margin = new Thickness(10);

Rectangle myRectangle = new Rectangle();

myRectangle.Name = "myRectangle";

this.RegisterName(myRectangle.Name, myRectangle);

myRectangle.Width = 100;

myRectangle.Height = 100;

myRectangle.Fill = Brushes.Blue;

myPanel.Children.Add(myRectangle);

this.Content = myPanel;

}

}

}

Copiar código

...

<DoubleAnimation From="1.0" To="0.0" />

...

Copiar código

DoubleAnimation myDoubleAnimation = new DoubleAnimation();

myDoubleAnimation.From = 1.0;

myDoubleAnimation.To = 0.0;

Copiar código

...

<DoubleAnimation From="1.0" To="0.0" Duration="0:0:5" />

...

Copiar código

myDoubleAnimation.Duration = new Duration(TimeSpan.FromSeconds(5));

Copiar código

...

<DoubleAnimation From="1.0" To="0.0" Duration="0:0:5" AutoReverse="True" RepeatBehavior="Forever"/>

...

Copiar código

myDoubleAnimation.Duration = new Duration(TimeSpan.FromSeconds(5));

myDoubleAnimation.RepeatBehavior = RepeatBehavior.Forever;

Copiar código

En el código, declare Storyboard como un miembro de clase.

A continuación, inicialice Storyboard y agregue la animación como su elemento secundario.

2. Storyboard debe saber dónde aplicar la animación. Use la propiedad asociada Storyboard.TargetName para especificar el objeto que desea animar. En el código siguiente, a DoubleAnimation se le asigna el nombre de destino de MyRectangle, que es el nombre del

objeto que se va a animar.

3. Use la propiedad asociada TargetProperty para especificar la propiedad que desea animar. En el código siguiente, la animación se configura para tener como destino la propiedad Opacity de Rectangle.

Para obtener más información acerca de la sintaxis de TargetProperty y más ejemplos, vea Información general sobre objetos Storyboard.

Parte 3 (XAML): Asociar el guión gráfico a un desencadenador

La manera más fácil de aplicar e iniciar un elemento Storyboard en XAML es usar un desencadenador de eventos.

Cree un objeto BeginStoryboard y asóciele su guión gráfico. BeginStoryboard es un tipo de TriggerAction que aplica e inicia Storyboard.

Cree un EventTrigger y agregue BeginStoryboard a su colección Actions. Establezca la propiedad RoutedEvent de EventTrigger en el evento enrutado que desee para iniciar Storyboard. Para obtener más información acerca de los eventos enrutados, vea Información general sobre eventos enrutados.

...

<Storyboard>

<DoubleAnimation

From="1.0" To="0.0" Duration="0:0:1"

AutoReverse="True" RepeatBehavior="Forever" />

</Storyboard>

...

Copiar código

public class RectangleOpacityFadeExample : Page

{

private Storyboard myStoryboard;

Copiar código

myStoryboard = new Storyboard();

myStoryboard.Children.Add(myDoubleAnimation);

Copiar código

...

<Storyboard>

<DoubleAnimation

Storyboard.TargetName="MyRectangle"

From="1.0" To="0.0" Duration="0:0:1"

AutoReverse="True" RepeatBehavior="Forever" />

</Storyboard>

...

Copiar código

Storyboard.SetTargetName(myDoubleAnimation, myRectangle.Name);

Nota:

Cuando se crean guiones gráficos en el código, es necesario realizar dos pasos adicionales: crear un ámbito de nombres y registrar el nombre del objeto que se va a animar. En el código incluido al principio de esta sección para crear la página y el rectángulo también se declaraba un objeto NameScope y se registraba un nombre para el rectángulo. Use el método SetNameScope para crear NameScope, si todavía no existe. Use el método RegisterName para registrar el nombre del objeto de destino con el elemento para el que creó NameScope. De lo contrario, Storyboard no encontrará el objeto para animarlo. Para obtener otro ejemplo, vea Cómo: Definir un ámbito de nombres.

XAML Copiar código

<BeginStoryboard>

<Storyboard>

<DoubleAnimation

Storyboard.TargetName="MyRectangle"

Storyboard.TargetProperty="Opacity"

From="1.0" To="0.0" Duration="0:0:5"

AutoReverse="True" RepeatBehavior="Forever" />

</Storyboard>

</BeginStoryboard>

Copiar código

Storyboard.SetTargetProperty(myDoubleAnimation, new PropertyPath(Rectangle.OpacityProperty));

XAML Copiar código

<BeginStoryboard>

<Storyboard>

<DoubleAnimation

Storyboard.TargetName="MyRectangle"

Storyboard.TargetProperty="Opacity"

From="1.0" To="0.0" Duration="0:0:5"

AutoReverse="True" RepeatBehavior="Forever" />

</Storyboard>

</BeginStoryboard>

XAML Copiar código

Agregue EventTrigger a la colección Triggers del rectángulo.

Parte 3 (código): Asociar el guión gráfico a un controlador de eventos

La manera más fácil de aplicar e iniciar un Storyboard en el código es usar un controlador de eventos.

1. Registre el evento Loaded del rectángulo.

[C#]

2. Declare el controlador de eventos. En el controlador de eventos, use el método Begin para aplicar el guión gráfico.

[C#]

Ejemplo completo

En el ejemplo siguiente se muestra el código completo que es necesario para crear un rectángulo que se intensifica y se atenúa hasta desaparecer.

<!-- Animates the rectangle's opacity. -->

<EventTrigger RoutedEvent="Rectangle.Loaded">

<BeginStoryboard>

<Storyboard>

<DoubleAnimation

Storyboard.TargetName="MyRectangle"

Storyboard.TargetProperty="Opacity"

From="1.0" To="0.0" Duration="0:0:5"

AutoReverse="True" RepeatBehavior="Forever" />

</Storyboard>

</BeginStoryboard>

</EventTrigger>

XAML Copiar código

<Rectangle

Name="MyRectangle"

Width="100"

Height="100"

Fill="Blue">

<Rectangle.Triggers>

<!-- Animates the rectangle's opacity. -->

<EventTrigger RoutedEvent="Rectangle.Loaded">

<BeginStoryboard>

<Storyboard>

<DoubleAnimation

Storyboard.TargetName="MyRectangle"

Storyboard.TargetProperty="Opacity"

From="1.0" To="0.0" Duration="0:0:5"

AutoReverse="True" RepeatBehavior="Forever" />

</Storyboard>

</BeginStoryboard>

</EventTrigger>

</Rectangle.Triggers>

</Rectangle>

Copiar código

myRectangle.Loaded += new RoutedEventHandler(myRectangleLoaded);

Copiar código

...

public void myRectangleLoaded(object sender, RoutedEventArgs e)

{

myStoryboard.Begin(this);

}

...

XAML Copiar código

<Page

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

WindowTitle="Fading Rectangle Example">

<StackPanel Margin="10">

<Rectangle

Name="MyRectangle"

Width="100"

Height="100"

Fill="Blue">

<Rectangle.Triggers>

<!-- Animates the rectangle's opacity. -->

<EventTrigger RoutedEvent="Rectangle.Loaded">

<BeginStoryboard>

<Storyboard>

<DoubleAnimation

Storyboard.TargetName="MyRectangle"

Storyboard.TargetProperty="Opacity"

From="1.0" To="0.0" Duration="0:0:5"

AutoReverse="True" RepeatBehavior="Forever" />

</Storyboard>

Tipos de animación

</BeginStoryboard>

</EventTrigger>

</Rectangle.Triggers>

</Rectangle>

</StackPanel>

</Page>

C# Copiar código

using System;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Shapes;

using System.Windows.Media;

using System.Windows.Media.Animation;

namespace SDKSample

{

public class RectangleOpacityFadeExample : Page

{

private Storyboard myStoryboard;

public RectangleOpacityFadeExample()

{

NameScope.SetNameScope(this, new NameScope());

this.WindowTitle = "Fading Rectangle Example";

StackPanel myPanel = new StackPanel();

myPanel.Margin = new Thickness(10);

Rectangle myRectangle = new Rectangle();

myRectangle.Name = "myRectangle";

this.RegisterName(myRectangle.Name, myRectangle);

myRectangle.Width = 100;

myRectangle.Height = 100;

myRectangle.Fill = Brushes.Blue;

DoubleAnimation myDoubleAnimation = new DoubleAnimation();

myDoubleAnimation.From = 1.0;

myDoubleAnimation.To = 0.0;

myDoubleAnimation.Duration = new Duration(TimeSpan.FromSeconds(5));

myDoubleAnimation.AutoReverse = true;

myDoubleAnimation.RepeatBehavior = RepeatBehavior.Forever;

myStoryboard = new Storyboard();

myStoryboard.Children.Add(myDoubleAnimation);

Storyboard.SetTargetName(myDoubleAnimation, myRectangle.Name);

Storyboard.SetTargetProperty(myDoubleAnimation, new PropertyPath(Rectangle.OpacityProperty));

// Use the Loaded event to start the Storyboard.

myRectangle.Loaded += new RoutedEventHandler(myRectangleLoaded);

myPanel.Children.Add(myRectangle);

this.Content = myPanel;

}

public void myRectangleLoaded(object sender, RoutedEventArgs e)

{

myStoryboard.Begin(this);

}

}

}

Dado que las animaciones generan valores de propiedad, existen distintos tipos de animaciones para los diversos tipos de propiedades. Para animar una propiedad que acepta una estructura Double, como la propiedad Width de un elemento, se usa una animación que genera valores Double. Para animar una propiedad que acepta una estructura Point, se usa una animación que genera valores Point; y así sucesivamente. Dado que existen tipos de propiedades diferentes, hay varias clases de animación en el espacio de nombres System.Windows.Media.Animation. Afortunadamente se rigen por una convención de nomenclatura estricta que hace que sea fácil diferenciarlas:

� <Tipo>Animation

Conocidas como animaciones "From/To/By" o "basic", generan una animación entre un valor inicial y de destino o agregan un valor de desplazamiento al valor inicial.

� Para especificar un valor inicial, establezca la propiedad From de la animación.

� Para especificar un valor final, establezca la propiedad To de la animación.

� Para especificar un valor de desplazamiento, establezca la propiedad By de la animación.

En los ejemplos de este tema se incluyen estas animaciones porque son las más fáciles de usar. Las animaciones From/To/By se describen en detalle en Información general sobre animaciones From/To/By.

� <<Tipo>AnimationUsingKeyFrames

Las animaciones de fotogramas clave son más eficaces que las animaciones From/To/By porque se puede especificar cualquier número de valores de destino e incluso controlar su método de interpolación. Algunos tipos solo se pueden animar con animaciones de fotogramas clave. Las animaciones de fotogramas clave se describen con detalle en Información general sobre animaciones de fotogramas clave.

� <<Tipo>AnimationUsingPath

Las animaciones de trazado permiten usar un trazado geométrico para generar valores animados.

� <<Tipo>AnimationBase

Clase abstracta que, cuando se implementa, anima un valor de <Tipo>. Esta clase actúa como clase base para las clases <Tipo>Animation y <Tipo>AnimationUsingKeyFrames. Tiene que tratar directamente con estas clases solo si desea crear sus propias animaciones personalizadas. En caso contrario, use <Tipo>Animation o KeyFrame<Tipo>Animation.

En la mayoría de los casos, deseará usar las clases <Tipo>Animation, como DoubleAnimation y ColorAnimation.

La tabla siguiente muestra varios tipos de animación comunes y algunas propiedades con las que se usan.

Las animaciones son escalas de tiempo

Todos los tipos de animaciones heredan de la clase Timeline, por lo que todas las animaciones son tipos de escalas de tiempo especializados. Un objeto Timeline define un segmento de tiempo. Puede especificar los comportamientos de temporización de una escala de tiempo: su Duration, cuántas veces se repite e incluso con qué rapidez pasa el tiempo para ella.

Dado que una animación es un objeto Timeline, también representa un segmento de tiempo. Una animación también calcula los valores de salida a medida que avanza por su segmento de tiempo (o Duration). A medida que la animación avanza, o se "reproduce", actualiza la propiedad a la que está asociada.

Tres propiedades de temporización que se usan con frecuencia son Duration, AutoReverse y RepeatBehavior.

Propiedad Duration

Como se ha mencionado previamente, una escala de tiempo representa un segmento de tiempo. La propiedad Duration de la escala de tiempo, que normalmente se especifica mediante un valor TimeSpan, determina la longitud de ese segmento. Cuando una escala de tiempo llega al final de su duración, ha completado una iteración.

Una animación usa su propiedad Duration para determinar su valor actual. Si no especifica un valor Duration para una animación, se usa 1 segundo, que es el valor predeterminado.

La sintaxis siguiente muestra una versión simplificada de la sintaxis de atributo de Lenguaje de marcado de aplicaciones extensible (XAML) para la propiedad Duration.

La tabla siguiente muestra varias configuraciones de Duration y sus valores resultantes.

Una manera de especificar Duration en el código es usar el método FromSeconds para crear un elemento TimeSpan y después declarar una nueva estructura Duration mediante TimeSpan.

Para obtener más información acerca de los valores de Duration y la sintaxis de Lenguaje de marcado de aplicaciones extensible (XAML) completa, vea la página del tipo Duration.

AutoReverse

La propiedad AutoReverse especifica si una escala de tiempo se vuelve a reproducir hacia atrás al llegar al final de Duration. Si establece esta propiedad de animación en true, la animación se invierte después de llegar al fin de Duration y se reproduce desde su valor final hasta su valor inicial. De forma predeterminada, esta propiedad es false.

RepeatBehavior

Tipo de propiedad

Animación básica correspondiente (From/To/By)

Animación de fotogramas clave correspondiente

Animación de trazado correspondiente

Ejemplo de uso

Color ColorAnimation ColorAnimationUsingKeyFrames Ninguna Animar la propiedad Color de un objeto SolidColorBrush o GradientStop.

Double DoubleAnimation DoubleAnimationUsingKeyFrames DoubleAnimationUsingPath Animar la propiedad Width de un objeto DockPanel o la propiedad Height de un objeto Button.

Point PointAnimation PointAnimationUsingKeyFrames PointAnimationUsingPath Animar la posición Center de un objeto EllipseGeometry.

String Ninguna StringAnimationUsingKeyFrames Ninguna Animar la propiedad Text de un objeto TextBlock o la propiedad Content de un objeto Button.

horas : minutes : seconds

Configuración Valor resultante

0:0:5.5 5,5 segundos.

0:30:5.5 30 minutos y 5,5 segundos.

1:30:5.5 1 hora, 30 minutos y 5,5 segundos.

Aplicar una animación a una propiedad

Control interactivo de guiones gráficos

Comportamiento tras la finalización de una animación

La propiedad RepeatBehavior especifica cuántas veces se reproduce una escala de tiempo. De forma predeterminada, las escalas de tiempo tienen una iteración de 1.0, lo que significa que se reproducen una vez y no se repiten en absoluto.

Para obtener más información acerca de estas propiedades y otras, vea Información general sobre comportamientos de control de tiempo.

En las secciones anteriores se han descrito los distintos tipos de animaciones y sus propiedades de temporización. En esta sección se muestra cómo aplicar la animación a la propiedad que se desea animar. Los objetos Storyboard proporcionan una manera de aplicar animaciones a propiedades. Storyboard es una escala de tiempo contenedora que proporciona información de destino para las animaciones que contiene.

Objetos y propiedades de destino

La clase Storyboard proporciona las propiedades asociadas TargetName y TargetProperty. Al establecer estas propiedades en una animación, se indica a la animación qué debe animar. Sin embargo, para que una animación pueda tener un objeto como destino, normalmente se debe dar un nombre al objeto.

Asignar un nombre a un FrameworkElement difiere de asignar un nombre a un objeto Freezable. La mayoría de los controles y paneles son elementos de marco, pero los objetos gráficos más puros, como los pinceles, las transformaciones y las formas geométricas, son objetos inmovilizables. Si no tiene la certeza de si un tipo es FrameworkElement o Freezable, consulte la sección Jerarquía de herencia de la página del tipo.

� Para convertir un FrameworkElement en un destino de animación, se le asigna un nombre mediante el establecimiento de su propiedad Name. En el código también se debe usar el método RegisterName para registrar el nombre del elemento con la página a la que pertenece.

� Para convertir un objeto Freezable en un destino en XAML, se usa el Atributo x:Name para asignarle un nombre. En el código simplemente se usa el método RegisterName para registrar el objeto con la página a la que pertenece.

En las secciones siguientes se proporciona un ejemplo de cómo asignar un nombre a un elemento en XAML y en el código. Para obtener información más detallada acerca de la asignación de nombres y destinos, vea Información general sobre objetos Storyboard.

Aplicar e iniciar guiones gráficos

Para iniciar un guión gráfico en XAML, se asocia a un EventTrigger. Un EventTrigger es un objeto que describe qué acciones deben realizarse cuando se produce un evento especificado. Una de esas acciones puede ser una acción BeginStoryboard, que se usa para iniciar el guión gráfico. Los desencadenadores de eventos son similares en concepto a los controladores de eventos, porque permiten especificar cómo responde una aplicación a un evento determinado. A diferencia de los controladores de eventos, los desencadenadores de eventos se pueden describir totalmente en XAML; no se requiere ningún otro código.

Para iniciar un Storyboard en el código, se puede usar EventTrigger o el método Begin de la clase Storyboard.

En el ejemplo anterior se mostró cómo iniciar Storyboard cuando se produce un evento. Un Storyboard también se puede controlar interactivamente después haberse iniciado: puede pausar, reanudar, detener, hacer que avance hasta su período de relleno, buscar y quitar el Storyboard. Para obtener más información y un ejemplo que muestra cómo controlar interactivamente un Storyboard, vea Información general sobre objetos Storyboard.

La propiedad FillBehavior especifica cómo se comporta una escala de tiempo cuando finaliza. De forma predeterminada, una escala de tiempo inicia el proceso Filling cuando finaliza. Una animación que se encuentra en el proceso Filling mantiene su valor de salida final.

El objeto DoubleAnimation del ejemplo anterior no finaliza porque su propiedad RepeatBehavior está establecida en Forever. En el ejemplo siguiente se anima un rectángulo mediante el uso de una animación similar. A diferencia del ejemplo anterior, las propiedades RepeatBehavior y AutoReverse de esta animación se mantienen en sus valores predeterminados. Por consiguiente, la animación progresa de 1 a 0 en cinco segundos y, a continuación, se detiene.

XAML Copiar código

<Rectangle

Name="MyRectangle"

Width="100"

Height="100"

Fill="Blue">

<Rectangle.Triggers>

<!-- Animates the rectangle's opacity. -->

<EventTrigger RoutedEvent="Rectangle.Loaded">

<BeginStoryboard>

<Storyboard>

<DoubleAnimation

Storyboard.TargetName="MyRectangle"

Storyboard.TargetProperty="Opacity"

From="1.0" To="0" Duration="0:0:5" />

</Storyboard>

</BeginStoryboard>

</EventTrigger>

</Rectangle.Triggers>

</Rectangle>

C# Copiar código

DoubleAnimation myDoubleAnimation = new DoubleAnimation();

myDoubleAnimation.From = 1.0;

Animaciones con enlace de datos y animaciones animadas

Otras maneras de crear animaciones

Ejemplos de animaciones

Vea también

Dado que no se modificó el valor predeterminado de su FillBehavior, que es HoldEnd, la animación mantiene su valor final, 0, cuando finaliza. Por tanto, la propiedad Opacity del rectángulo se mantiene en 0 después de que finaliza la animación. Si establece la propiedad Opacity del rectángulo en otro valor, aparentemente su código no tiene ningún efecto, porque la animación todavía influye en la propiedad Opacity.

Una manera de recobrar el control de una propiedad animada en el código es usar el método BeginAnimation y especificar null para el parámetro AnimationTimeline. Para obtener más información y un ejemplo, vea Cómo: Establecer una propiedad después de animarla con un guión gráfico.

Tenga en cuenta que, aunque parece que no tiene ningún efecto establecer un valor de una propiedad que tiene una animación Active o Filling, el valor de la propiedad realmente cambia. Para obtener más información, vea Información general sobre sistemas de temporización y animación.

myDoubleAnimation.To = 0.0;

myDoubleAnimation.Duration = new Duration(TimeSpan.FromSeconds(5));

La mayoría de las propiedades de animación pueden ser enlazadas a datos o animadas; por ejemplo, puede animar la propiedad Duration de DoubleAnimation. Sin embargo, debido a la manera en que funciona el sistema de temporización, las animaciones enlazadas a datos o animadas no se comportan como los demás objetos enlazados a datos o animados. Para entender su comportamiento, le será útil comprender el significado de aplicar una animación a una propiedad.

Consulte el ejemplo de la sección anterior que mostraba cómo animar la propiedad Opacity de un rectángulo. Cuando se carga el rectángulo del ejemplo anterior, su desencadenador de eventos aplica el elemento Storyboard. El sistema de temporización crea una copia de Storyboard y de su animación. Estas copias se inmovilizan (se convierten en copias de sólo lectura) y a partir de ellas se crean objetos Clock. Estos relojes son los que realmente se encargan de animar las propiedades de destino.

El sistema de temporización crea un reloj para DoubleAnimation y lo aplica al objeto y a la propiedad que se especifican mediante las propiedades TargetName y TargetProperty de DoubleAnimation. En este caso, el sistema de temporización aplica el reloj a la propiedad Opacity del objeto denominado "MyRectangle".

Aunque también se crea un reloj para Storyboard, el reloj no se aplica a ninguna propiedad. Su finalidad es controlar a su reloj secundario, el creado para DoubleAnimation.

Para que una animación refleje cambios de enlace de datos o de animación, su reloj se debe regenerar. Los relojes no se regeneran automáticamente. Para que una animación refleje los cambios, vuelva a aplicar su guión gráfico mediante un elemento BeginStoryboard o el método Begin. Al usar cualquiera de estos métodos, la animación se reinicia. En el código, puede usar el método Seek para hacer que el guión gráfico regrese a su posición anterior.

Para obtener un ejemplo de una animación enlazada a datos, vea Ejemplo Key Spline Animation. Para obtener más información acerca del funcionamiento del sistema de animación y temporización, vea Información general sobre sistemas de temporización y animación.

Los ejemplos de este tema muestran cómo aplicar animaciones mediante guiones gráficos. En el código se pueden aplicar animaciones de otras maneras. Para obtener más información, vea Información general sobre técnicas de animación de propiedades.

Los ejemplos siguientes pueden ayudarle a familiarizarse con la forma de agregar animaciones a sus aplicaciones.

� Ejemplo Property Animation

Muestra cómo aplicar animaciones a elementos de marco y a objetos inmovilizables.

� Ejemplo From, To, and By Animation Target Values

Muestra distintas configuraciones From/To/By.

� Ejemplo Animation Timing Behavior

Muestra las distintas maneras de controlar el comportamiento de temporización de una animación. Este ejemplo también muestra cómo enlazar a datos el valor de destino de una animación.

Conceptos

Información general sobre animaciones From/To/By

Información general sobre animaciones de fotogramas clave

Información general sobre objetos Storyboard

Información general sobre comportamientos de control de tiempo

Información general sobre sistemas de temporización y animación

Información general sobre eventos de control de tiempo

Información general sobre Windows Presentation Foundation

Referencia

Timeline

Storyboard

Enviar comentarios sobre este tema a Microsoft.

Contraer todo Código: Todos

Windows Presentation Foundation

Tutorial: Crear un botón mediante el uso de XAMLVea también Enviar comentarios

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

La figura siguiente muestra los botones acabados.

Crear botones básicos

Nota importante:

Este tutorial sirve como guía en los pasos necesarios para crear la aplicación escribiendo, o copiando y pegando Lenguaje de marcado de aplicaciones extensible (XAML) en Microsoft Visual Studio. Si prefiere aprender a usar una herramienta de diseño (Microsoft Expression Blend) para crear la misma aplicación, vea Tutorial: Crear un botón mediante Microsoft Expression Blend.

Empecemos por crear un nuevo proyecto y agregar unos botones a la ventana.

Para crear un nuevo proyecto de WPF y agregar botones a la ventana

1. Inicie Visual Studio.

2. Cree un nuevo proyecto de WPF: En el menú Archivo, señale a Nuevo y, a continuación, haga clic en Proyecto. Se abre la ventana que se muestra en la ilustración siguiente. En el panel de la izquierda, bajo el nodo Visual C#, seleccione .NET Framework 3.0. En el panel de la derecha, seleccione la plantilla Aplicación para Windows (WPF). Llame al proyecto "AnimatedButton". Esto creará el esqueleto para la aplicación.

3. Agregue los botones predeterminados básicos: la plantilla proporciona todos los archivos que necesita para este tutorial. Abra el archivo Window1.xaml haciendo doble clic en él en el Explorador de soluciones. De forma predeterminada, hay un elemento Grid en Window1.xaml. Quite el elemento Grid y agregue unos botones a la página Lenguaje de marcado de aplicaciones extensible (XAML) escribiendo o copiando y pegando el siguiente código resaltado en Window1.xaml:

Copiar código

<Window x:Class="AnimatedButton.Window1"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

Title="AnimatedButton" Height="300" Width="300"

Background="Black">

<!-- Buttons arranged vertically inside a StackPanel. -->

<StackPanel HorizontalAlignment="Left">

<Button>Button 1</Button>

<Button>Button 2</Button>

<Button>Button 3</Button>

Establecer propiedades básicas

Presione F5 para ejecutar la aplicación; debería ver un conjunto de botones parecido a la ilustración siguiente.

Ahora que ha creado los botones básicos, ha terminado de trabajar en el archivo Window1.xaml. El resto del tutorial se centra en el archivo app.xaml, definiendo estilos y una plantilla para los botones.

</StackPanel>

</Window>

A continuación, establezcamos algunas propiedades de estos botones para controlar su aspecto y su diseño. En lugar de establecer individualmente las propiedades de los botones, utilizará recursos para definir las propiedades de botón de toda la aplicación. Los recursos de aplicación son conceptualmente similares a Hojas de estilos en cascada (CSS) externas para páginas web; sin embargo, los recursos son mucho más eficaces que Hojas de estilos en cascada (CSS), como verá al final de este tutorial. Para obtener más información sobre los recursos, vea Información general sobre recursos.

Para utilizar estilos para establecer propiedades básicas en los botones

1. Defina un bloque Application.Resources: abra app.xaml y agregue el marcado resaltado siguiente si aún no está allí:

El ámbito del recurso lo determina dónde se defina el recurso. Definir recursos en Application.Resoureses en el archivo app.xaml permite utilizar el recurso en cualquier parte de la aplicación. Para obtener más información sobre cómo definir el ámbito de los recursos, vea Información general sobre recursos.

2. Cree un estilo y defina los valores de las propiedades básicas con él: agregue el marcado siguiente al bloque Application.Resources. Este marcado crea un objeto Style que se aplica a todos los botones de la aplicación, estableciendo la propiedad Width de los botones en 90 y Margin en 10:

La propiedad TargetType especifica que el estilo se aplica a todos los objetos de tipo Button. Cada Setter establece un valor de la propiedad diferente para el objeto Style. Por consiguiente, en este punto cada botón de la aplicación tiene un ancho de 90 y un margen de 10. Si presiona F5 para ejecutar la aplicación, verá la ventana siguiente.

Copiar código

<Application x:Class="AnimatedButton.App"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

StartupUri="Window1.xaml"

>

<Application.Resources>

<!-- Resources for the entire application can be

defined here. -->

</Application.Resources>

</Application>

Copiar código

<Application.Resources>

<Style TargetType="Button">

<Setter Property="Width" Value="90" />

<Setter Property="Margin" Value="10" />

</Style>

</Application.Resources>

Crear una plantilla que define la apariencia del botón

Hay mucho más que puede hacer con estilos, incluidas diversas maneras de ajustar con precisión a qué objetos se destinan, especificar valores de propiedad complejos e incluso utilizar estilos como entrada para otros estilos. Para obtener más información, vea Styling and Templating Overview.

3. Establezca un valor de propiedad de estilo en un recurso: los recursos permiten reutilizar fácilmente objetos y valores que se definen con frecuencia. Es especialmente útil definir valores complejos utilizando recursos, para hacer el código más modular. Agregue el marcado resaltado siguiente a app.xaml.

Directamente bajo el bloque Application.Resources, creó un recurso llamado "GrayBlueGradientBrush". Este recurso define un degradado horizontal. Este recurso se puede utilizar en cualquier parte de la aplicación como un valor de propiedad, incluso dentro del establecedor de estilo del botón para la propiedad Background. Ahora, todos los botones tienen un valor de propiedad Background de este degradado.

Presione F5 para ejecutar la aplicación. Debe tener este aspecto:

Copiar código

<Application.Resources>

<LinearGradientBrush x:Key="GrayBlueGradientBrush"

StartPoint="0,0" EndPoint="1,1">

<GradientStop Color="DarkGray" Offset="0" />

<GradientStop Color="#CCCCFF" Offset="0.5" />

<GradientStop Color="DarkGray" Offset="1" />

</LinearGradientBrush>

<Style TargetType="{x:Type Button}">

<Setter Property="Background"

Value="{StaticResource GrayBlueGradientBrush}" />

<Setter Property="Width" Value="80" />

<Setter Property="Margin" Value="10" />

</Style>

</Application.Resources>

En esta sección creará una plantilla que personaliza la apariencia (presentación) del botón. La presentación del botón se compone de varios objetos, que incluyen rectángulos y otros componentes para dar una apariencia única al botón.

Hasta ahora, el control de la apariencia de los botones de la aplicación se ha confinado a cambiar propiedades del botón. ¿Qué ocurre si desea realizar cambios más radicales en la apariencia del botón? Las plantillas permiten un control eficaz sobre la presentación de un objeto. Dado que las plantillas se pueden utilizar dentro de estilos, puede aplicar una plantilla a todos los objetos a los que se aplica el estilo (en este tutorial, el botón).

Para utilizar la plantilla para definir la apariencia del botón

1. Configure la plantilla: dado que los controles como Button tienen una propiedad Template, puede definir el valor de la propiedad de la plantilla igual que los demás valores de propiedades que hemos establecido en un objeto Style, utilizando un objeto Setter. Agregue el marcado resaltado siguiente al estilo de botón.

Copiar código

<Application.Resources>

<LinearGradientBrush x:Key="GrayBlueGradientBrush"

2. Modifique la presentación del botón: en este punto, debe definir la plantilla. Agregue el siguiente marcado resaltado: Este marcado especifica dos elementos Rectangle con bordes redondeados, seguidos por un control DockPanel. El control DockPanel se utiliza para hospedar el objeto ContentPresenter del botón. Un objeto ContentPresenter muestra el contenido del botón. En este tutorial, el contenido es texto ("Button 1", "Button 2", "Button 3"). Todos los componentes de la plantilla (los rectángulos y el control DockPanel) se disponen en el interior de un control Grid.

Presione F5 para ejecutar la aplicación.

1. Agregue un efecto de vidrio a la plantilla: a continuación agregará el vidrio. Primero cree algunos recursos que creen un efecto de degradado de vidrio. Agregue estos recursos de degradado en cualquier punto del bloque Application.Resources:

Estos recursos se utilizan como propiedad Fill para un rectángulo que insertamos en el control Grid de la plantilla de botón. Agregue el siguiente marcado resaltado a la plantilla.

StartPoint="0,0" EndPoint="1,1">

<GradientStop Color="DarkGray" Offset="0" />

<GradientStop Color="#CCCCFF" Offset="0.5" />

<GradientStop Color="DarkGray" Offset="1" />

</LinearGradientBrush>

<Style TargetType="{x:Type Button}">

<Setter Property="Background" Value="{StaticResource GrayBlueGradientBrush}" />

<Setter Property="Width" Value="80" />

<Setter Property="Margin" Value="10" />

<Setter Property="Template">

<Setter.Value>

<!-- The button template is defined here. -->

</Setter.Value>

</Setter>

</Style>

</Application.Resources>

Copiar código

<Setter.Value>

<ControlTemplate TargetType="Button">

<Grid Width="{TemplateBinding Width}"

Height="{TemplateBinding Height}" ClipToBounds="True">

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

<Rectangle x:Name="outerRectangle"

HorizontalAlignment="Stretch"

VerticalAlignment="Stretch"

Stroke="{TemplateBinding Background}"

RadiusX="20" RadiusY="20" StrokeThickness="5"

Fill="Transparent" />

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

<Rectangle x:Name="innerRectangle"

HorizontalAlignment="Stretch"

VerticalAlignment="Stretch" Stroke="Transparent"

StrokeThickness="20"

Fill="{TemplateBinding Background}"

RadiusX="20" RadiusY="20" />

<!-- Present Content (text) of the button. -->

<DockPanel Name="myContentPresenterDockPanel">

<ContentPresenter x:Name="myContentPresenter" Margin="20"

Content="{TemplateBinding Content}"

TextBlock.Foreground="Black" />

</DockPanel>

</Grid>

</ControlTemplate>

</Setter.Value>

Copiar código

<Application.Resources>

<GradientStopCollection x:Key="MyGlassGradientStopsResource">

<GradientStop Color="WhiteSmoke" Offset="0.2" />

<GradientStop Color="Transparent" Offset="0.4" />

<GradientStop Color="WhiteSmoke" Offset="0.5" />

<GradientStop Color="Transparent" Offset="0.75" />

<GradientStop Color="WhiteSmoke" Offset="0.9" />

<GradientStop Color="Transparent" Offset="1" />

</GradientStopCollection>

<LinearGradientBrush x:Key="MyGlassBrushResource"

StartPoint="0,0" EndPoint="1,1" Opacity="0.75"

GradientStops="{StaticResource MyGlassGradientStopsResource}" />

<!-- Styles and other resources below here. -->

Copiar código

<Setter.Value>

<ControlTemplate TargetType="{x:Type Button}">

<Grid Width="{TemplateBinding Width}" Height="{TemplateBinding Height}"

ClipToBounds="True">

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

Crear la interactividad del botón

Observe que la propiedad Opacity del rectángulo con la propiedad x:Name de "glassCube" es 0, por lo que al ejecutar el ejemplo no verá el rectángulo de vidrio superpuesto. Esto se debe a que agregaremos después a la plantilla los desencadenadores para cuando el usuario interactúe con el botón. Sin embargo, puede ver la apariencia que tiene ahora el botón cambiando el valor Opacity a 1 y ejecutando la aplicación. Vea la ilustración siguiente. Antes de continuar con el paso siguiente, vuelva a establecer Opacity en 0.

<Rectangle x:Name="outerRectangle" HorizontalAlignment="Stretch"

VerticalAlignment="Stretch" Stroke="{TemplateBinding Background}"

RadiusX="20" RadiusY="20" StrokeThickness="5" Fill="Transparent" />

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

<Rectangle x:Name="innerRectangle" HorizontalAlignment="Stretch"

VerticalAlignment="Stretch" Stroke="Transparent" StrokeThickness="20"

Fill="{TemplateBinding Background}" RadiusX="20" RadiusY="20" />

<!-- Glass Rectangle -->

<Rectangle x:Name="glassCube" HorizontalAlignment="Stretch"

VerticalAlignment="Stretch"

StrokeThickness="2" RadiusX="10" RadiusY="10" Opacity="0"

Fill="{StaticResource MyGlassBrushResource}"

RenderTransformOrigin="0.5,0.5">

<Rectangle.Stroke>

<LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">

<LinearGradientBrush.GradientStops>

<GradientStop Offset="0.0" Color="LightBlue" />

<GradientStop Offset="1.0" Color="Gray" />

</LinearGradientBrush.GradientStops>

</LinearGradientBrush>

</Rectangle.Stroke>

<!-- These transforms have no effect as they are declared here.

The reason the transforms are included is to be targets

for animation (see later). -->

<Rectangle.RenderTransform>

<TransformGroup>

<ScaleTransform />

<RotateTransform />

</TransformGroup>

</Rectangle.RenderTransform>

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

"Beveled" look. -->

<Rectangle.BitmapEffect>

<BevelBitmapEffect />

</Rectangle.BitmapEffect>

</Rectangle>

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

<DockPanel Name="myContentPresenterDockPanel">

<ContentPresenter x:Name="myContentPresenter" Margin="20"

Content="{TemplateBinding Content}" TextBlock.Foreground="Black" />

</DockPanel>

</Grid>

</ControlTemplate>

</Setter.Value>

En esta sección, creará desencadenadores de propiedad y desencadenadores de evento para cambiar valores de propiedad y ejecutar animaciones en respuesta a acciones del usuario tales como mover el puntero del mouse sobre el botón y hacer clic.

Una manera fácil de agregar interactividad (entrada de mouse, salida de mouse, clic, etc.) es definir los desencadenadores dentro de la plantilla o del estilo. Para crear un objeto Trigger, defina una propiedad "condición" tal como: el valor de la propiedad IsMouseOver del botón es igual a true. A continuación, defina establecedores (acciones) que tengan lugar cuando la condición de activación sea verdadera.

Para crear la interactividad del botón

1. Agregue desencadenadores de plantilla: agregue el marcado resaltado a la plantilla.

2. Agregue desencadenadores de propiedad: agregue el marcado resaltado al bloque ControlTemplate.Triggers:

Copiar código

<Setter.Value>

<ControlTemplate TargetType="{x:Type Button}">

<Grid Width="{TemplateBinding Width}"

Height="{TemplateBinding Height}" ClipToBounds="True">

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

<Rectangle x:Name="outerRectangle" HorizontalAlignment="Stretch"

VerticalAlignment="Stretch" Stroke="{TemplateBinding Background}"

RadiusX="20" RadiusY="20" StrokeThickness="5" Fill="Transparent" />

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

<Rectangle x:Name="innerRectangle" HorizontalAlignment="Stretch"

VerticalAlignment="Stretch" Stroke="Transparent"

StrokeThickness="20"

Fill="{TemplateBinding Background}" RadiusX="20" RadiusY="20"

/>

<!-- Glass Rectangle -->

<Rectangle x:Name="glassCube" HorizontalAlignment="Stretch"

VerticalAlignment="Stretch"

StrokeThickness="2" RadiusX="10" RadiusY="10" Opacity="0"

Fill="{StaticResource MyGlassBrushResource}"

RenderTransformOrigin="0.5,0.5">

<Rectangle.Stroke>

<LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">

<LinearGradientBrush.GradientStops>

<GradientStop Offset="0.0" Color="LightBlue" />

<GradientStop Offset="1.0" Color="Gray" />

</LinearGradientBrush.GradientStops>

</LinearGradientBrush>

</Rectangle.Stroke>

<!-- These transforms have no effect as they

are declared here.

The reason the transforms are included is to be targets

for animation (see later). -->

<Rectangle.RenderTransform>

<TransformGroup>

<ScaleTransform />

<RotateTransform />

</TransformGroup>

</Rectangle.RenderTransform>

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

"Beveled" look. -->

<Rectangle.BitmapEffect>

<BevelBitmapEffect />

</Rectangle.BitmapEffect>

</Rectangle>

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

<DockPanel Name="myContentPresenterDockPanel">

<ContentPresenter x:Name="myContentPresenter" Margin="20"

Content="{TemplateBinding Content}" TextBlock.Foreground="Black" />

</DockPanel>

</Grid>

<ControlTemplate.Triggers>

<!-- Set action triggers for the buttons and define

what the button does in response to those triggers. -->

</ControlTemplate.Triggers>

</ControlTemplate>

</Setter.Value>

Copiar código

<ControlTemplate.Triggers>

<!-- Set properties when mouse pointer is over the button. -->

<Trigger Property="IsMouseOver" Value="True">

<!-- Below are three property settings that occur when the

condition is met (user mouses over button). -->

<!-- Change the color of the outer rectangle when user

mouses over it. -->

<Setter Property ="Rectangle.Stroke" TargetName="outerRectangle"

Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" />

<!-- Sets the glass opacity to 1, therefore, the

glass "appears" when user mouses over it. -->

<Setter Property="Rectangle.Opacity" Value="1" TargetName="glassCube" />

<!-- Makes the text slightly blurry as though you

were looking at it through blurry glass. -->

Presione F5 para ejecutar la aplicación y ver el efecto al pasar el puntero del mouse sobre los botones.

3. Agregue un desencadenador de foco: a continuación, agregaremos algunos establecedores similares para administrar el caso en el que el botón tenga el foco (por ejemplo, después de que el usuario haga clic en él).

Presione F5 para ejecutar la aplicación y haga clic en uno de los botones. Observa que el botón permanece resaltado después de hacer clic en él, porque todavía tiene el foco. Si hace clic en otro botón, el nuevo botón obtendrá el foco mientras el último lo pierde.

4. Agregue animaciones para MouseEnter yMouseLeave: a continuación agregamos algunas animaciones a los desencadenadores. Agregue el marcado siguiente en cualquier punto del bloque ControlTemplate.Triggers.

El rectángulo de vidrio se reduce cuando el puntero del mouse pasa sobre el botón y vuelve al tamaño normal cuando el puntero sale.

Hay dos animaciones que se desencadenan cuando el puntero pasa sobre el botón (cuando se provoca el evento MouseEnter). Estas animaciones reducen el rectángulo de vidrio a lo largo de los ejes X e Y. Observe las propiedades de los elementos DoubleAnimation, Duration y By. La propiedad Duration especifica que la animación se produce durante medio segundo, y By especifica que el vidrio

<Setter Property="ContentPresenter.BitmapEffect"

TargetName="myContentPresenter">

<Setter.Value>

<BlurBitmapEffect Radius="1" />

</Setter.Value>

</Setter>

</Trigger>

<ControlTemplate.Triggers/>

Copiar código

<ControlTemplate.Triggers>

<!-- Set properties when mouse pointer is over the button. -->

<Trigger Property="IsMouseOver" Value="True">

<!-- Below are three property settings that occur when the

condition is met (user mouses over button). -->

<!-- Change the color of the outer rectangle when user mouses over it. -->

<Setter Property ="Rectangle.Stroke" TargetName="outerRectangle"

Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" />

<!-- Sets the glass opacity to 1, therefore, the glass "appears" when user mouses over it. -->

<Setter Property="Rectangle.Opacity" Value="1" TargetName="glassCube" />

<!-- Makes the text slightly blurry as though you were looking at it through blurry glass. -->

<Setter Property="ContentPresenter.BitmapEffect" TargetName="myContentPresenter">

<Setter.Value>

<BlurBitmapEffect Radius="1" />

</Setter.Value>

</Setter>

</Trigger>

<!-- Set properties when button has focus. -->

<Trigger Property="IsFocused" Value="true">

<Setter Property="Rectangle.Opacity" Value="1" TargetName="glassCube" />

<Setter Property="Rectangle.Stroke" TargetName="outerRectangle"

Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" />

<Setter Property="Rectangle.Opacity" Value="1" TargetName="glassCube" />

</Trigger>

</ControlTemplate.Triggers>

Copiar código

<!-- Animations that start when mouse enters and leaves button. -->

<EventTrigger RoutedEvent="Mouse.MouseEnter">

<EventTrigger.Actions>

<BeginStoryboard Name="mouseEnterBeginStoryboard">

<Storyboard>

<!-- This animation makes the glass rectangle shrink in the X direction. -->

<DoubleAnimation Storyboard.TargetName="glassCube"

Storyboard.TargetProperty=

"(Rectangle.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)"

By="-0.1" Duration="0:0:0.5" />

<!-- This animation makes the glass rectangle shrink in the Y direction. -->

<DoubleAnimation

Storyboard.TargetName="glassCube"

Storyboard.TargetProperty=

"(Rectangle.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)"

By="-0.1" Duration="0:0:0.5" />

</Storyboard>

</BeginStoryboard>

</EventTrigger.Actions>

</EventTrigger>

<EventTrigger RoutedEvent="Mouse.MouseLeave">

<EventTrigger.Actions>

<!-- Stopping the storyboard sets all animated properties back to default. -->

<StopStoryboard BeginStoryboardName="mouseEnterBeginStoryboard" />

</EventTrigger.Actions>

</EventTrigger>

Resumen

Vea también

se reduce un 10%.

El segundo desencadenador de eventos (MouseLeave) detiene simplemente el primero. Al detener un objeto Storyboard, todas las propiedades animadas vuelven a sus valores predeterminados. Por consiguiente, cuando el usuario saca el puntero del botón, el botón vuelve a ser como era antes de que el puntero del mouse pasara sobre el botón. Para obtener más información acerca de las animaciones, vea Información general sobre animaciones.

5. Agregue una animación para cuando se haga clic en el botón: el paso final es agregar un desencadenador para cuando el usuario haga clic en el botón. Agregue el marcado siguiente en cualquier punto del bloque ControlTemplate.Triggers.

Presione F5 para ejecutar la aplicación y haga clic en uno de los botones. Al hacer clic en un botón, el rectángulo de vidrio gira sobre sí mismo.

Copiar código

<!-- Animation fires when button is clicked, causing glass to spin. -->

<EventTrigger RoutedEvent="Button.Click">

<EventTrigger.Actions>

<BeginStoryboard>

<Storyboard>

<DoubleAnimation Storyboard.TargetName="glassCube"

Storyboard.TargetProperty=

"(Rectangle.RenderTransform).(TransformGroup.Children)[1].(RotateTransform.Angle)"

By="360" Duration="0:0:0.5" />

</Storyboard>

</BeginStoryboard>

</EventTrigger.Actions>

</EventTrigger>

En este tutorial, ha realizado los siguientes ejercicios:

� Ha destinado un objeto Style a un tipo de objeto (Button).

� Ha controlado propiedades básicas de los botones en toda la aplicación utilizando el objeto Style.

� Ha creado recursos tales como degradados para utilizarlos para valores de propiedades de los establecedores de Style.

� Ha personalizado la apariencia de botones de toda la aplicación aplicando una plantilla a los botones.

� Ha personalizado el comportamiento de los botones en respuesta a acciones del usuario (tales como MouseEnter, MouseLeave y Click) incluyendo efectos de animación.

Conceptos

Tutorial: Crear un botón mediante Microsoft Expression Blend

Styling and Templating Overview

Información general sobre animaciones

Información general sobre el dibujo con colores sólidos y degradados

Información general sobre efectos de mapa de bits

Enviar comentarios sobre este tema a Microsoft.