You are on page 1of 137

Programacin en .

Net (Avanzado)
WPF

MARA TERESA CRESPI NOIR

PROGRAMACIN EN .NET (AVANZADO) - MANUAL WPF

Buffa Sistemas S.R.L 2010 Buenos Aires

Programacin en .Net (Avanzado) - Manual WPF Crespi Noir, Mara Teresa 1a Edicin Buffa Sistemas SRL Alsina 655 4 Piso Buenos Aires

ISBN N 978-987-25214-2-4

Multigraphic Avenida Belgrano 520 Capital Federal 10 de agosto de 2010

Crespi Noir, Mara Teresa Programacin en .Net (Avanzado) - Manual WPF Buenos Aires : Buffa Sistemas S.R.L., 2010. 307 p. ; 21 x 29,7 cm. ISBN 978-987-25214-2-4

(c), 2010 Buffa Sistemas SRL Queda hecho el depsito que establece la Ley 11.723. Libro de edicin Argentina

No se permite la reproduccin parcial o total, el almacenamiento, el alquiler, la transmisin o la transformacin de este libro, en cualquier forma o por cualquier medio, sea electrnico o mecnico, mediante fotocopias, digitalizacin u otros mtodos, sin el permiso previo y escrito del editor.Su infraccin est penada por las leyes 11723 y 25446.3

Windows Presentation Foundation (WPF)


4

NOTA: El material incluido en el presente puede contener datos y ejemplos extrados de sitios web pblicos sin restriccin de acceso. Los mismos son utilizados solamente a fines didcticos y pueden encontrarse en el final de la publicacin agrupados bajo el ttulo Links Relacionados.

MDULO 1 : INTRODUCCIN A WPF ..................................................................................... 12 1- Introduccin........................................................................................................................... 13 Definicin ................................................................................................................................ 13 Programar con WPF ............................................................................................................... 13 Cdigo de lenguaje marcado y cdigo subyacente ................................................................ 13 XAML ...................................................................................................................................... 13 Cdigo Subyacente ................................................................................................................. 14 Aplicaciones WPF ................................................................................................................... 15 Seguridad ................................................................................................................................ 15 2- Conceptos Bsicos ............................................................................................................... 15 Controles ................................................................................................................................. 15 Diseo ..................................................................................................................................... 15 Enlace de Datos ...................................................................................................................... 16 Grficos ................................................................................................................................... 16 Formas 2D .............................................................................................................................. 17 Geometras 2D ........................................................................................................................ 17 Efectos 2D ............................................................................................................................... 17 Representaciones 3D.............................................................................................................. 17 Animaciones ............................................................................................................................ 17 Multimedia ............................................................................................................................... 17 Texto y Tipografa ................................................................................................................... 18 Documentos ............................................................................................................................ 18 Anotaciones ............................................................................................................................ 18 Empaquetado .......................................................................................................................... 18 Impresin ................................................................................................................................ 18 Personalizacin ....................................................................................................................... 19 3- Eventos y Comandos ............................................................................................................ 20 Informacin general sobre Eventos Enrutados ....................................................................... 20 rboles de elementos WPF .................................................................................................... 21 Enrutamiento de eventos ........................................................................................................ 22 Eventos enrutados y composicin .......................................................................................... 22 Eventos adjuntos..................................................................................................................... 23 Informacin general sobre Comandos enrutados ................................................................... 23 Enrutamiento de comandos .................................................................................................... 25 Definicin de comandos .......................................................................................................... 25 Desafos de los comandos enrutados..................................................................................... 25 MDULO 2: CREANDO APLICACIONES WPF ........................................................................ 26 1- Crear una aplicacin WFP .................................................................................................... 27 Aplicacin WPF ....................................................................................................................... 27 Clase Window ......................................................................................................................... 28 Configurar la ventana de inicio ............................................................................................... 28 Propiedades de la Clase Window ........................................................................................... 29 Controles WPF y su equivalente con Controles Windows Forms .......................................... 29 Controladores de Eventos ...................................................................................................... 31 Recursos ................................................................................................................................. 32 Recursos Estticos y Dinmicos............................................................................................. 32 6

2- Controles de Diseo ............................................................................................................. 33 Sistema de Diseo de Interfase de Usuario ........................................................................... 33 Border ..................................................................................................................................... 34 Canvas .................................................................................................................................... 34 DockPanel ............................................................................................................................... 35 Grid.......................................................................................................................................... 36 StackPanel .............................................................................................................................. 37 GroupBox ................................................................................................................................ 37 Expander ................................................................................................................................. 38 InkCanvas ............................................................................................................................... 38 Menu ....................................................................................................................................... 39 Frame ...................................................................................................................................... 39 WrapPanel .............................................................................................................................. 40 3- Otros Controles ..................................................................................................................... 41 Label - AccessText.................................................................................................................. 41 TextBox ................................................................................................................................... 41 TextBlock ................................................................................................................................ 41 Button ...................................................................................................................................... 41 ListBox - ComboBox ............................................................................................................... 42 CheckBox ................................................................................................................................ 43 RadioButton ............................................................................................................................ 43 Otros Controles ....................................................................................................................... 44 4- Informacin General de Controles ...................................................................................... 45 Propiedades Generales de los Controles ............................................................................... 45 Creacin dinmica de controles .............................................................................................. 45 MDULO 3: PERSONALIZANDO LA APARIENCIA DE APLICACIONES WPF .................... 47 1- Personalizar Apariencia ....................................................................................................... 48 Composicin ........................................................................................................................... 48 Estilos ...................................................................................................................................... 48 Plantillas .................................................................................................................................. 50 Desencadenadores (Triggers) ................................................................................................ 52 2- Crear Controles de Usuario ................................................................................................. 54 Controles ................................................................................................................................. 54 Controles de Usuario .............................................................................................................. 54 Personalizando Controles de Usuario .................................................................................... 56 Controles Personalizados ....................................................................................................... 57 MDULO 4: ENLACE A DATOS ............................................................................................... 58 1- Enlazar Datos......................................................................................................................... 59 Enlace a Datos ........................................................................................................................ 59 Clase Binding ......................................................................................................................... 59 Modos de Enlazar Propiedad Mode..................................................................................... 59 Momento del Enlace ............................................................................................................... 60 Propiedad Asociadas al Enlace de Datos ............................................................................... 61 Enlace entre Controles ........................................................................................................... 62 XmlDataProvider ..................................................................................................................... 63 ObjectDataProvider ................................................................................................................. 64 7

MethodParameters.................................................................................................................. 65 DataTemplate.......................................................................................................................... 67 DataContext ............................................................................................................................ 68 Controles ListView - Gridview ................................................................................................. 69 2- Notificaciones de Cambio de Propiedad ............................................................................ 70 Interfase INotifyPropertyChanged ........................................................................................... 70 3- Convertir Datos ..................................................................................................................... 74 ValueConverters ..................................................................................................................... 74 Interfase IValueConverter ....................................................................................................... 74 4- Validar Datos ......................................................................................................................... 76 ValidationRules ....................................................................................................................... 76 Clase Binding.ValidationRule .................................................................................................. 77 IDataErrorInfo.......................................................................................................................... 79 ExceptionValidationRule ......................................................................................................... 81 DataErrorValidationRule ......................................................................................................... 81 MDULO 5: ENLACE A COLECCIONES ................................................................................. 82 1- Enlace a Colecciones ........................................................................................................... 83 Enlace a Colecciones.............................................................................................................. 83 Cmo implementar colecciones .............................................................................................. 83 2- Vistas de Colecciones .......................................................................................................... 86 Vistas de colecciones.............................................................................................................. 86 Cmo crear una vista .............................................................................................................. 86 Ordenar ................................................................................................................................... 86 Agrupar ................................................................................................................................... 87 Filtrar ....................................................................................................................................... 89 Punteros de elemento actual .................................................................................................. 91 Navegacin de Colecciones ................................................................................................... 91 MDULO 6: ADMINISTRAR DOCUMENTOS ........................................................................... 93 1- Documentos........................................................................................................................... 94 Definicin ................................................................................................................................ 94 Tipos de documentos .............................................................................................................. 94 2- Documentos Dinmicos (FlowDocuments) ........................................................................ 94 Definicin ................................................................................................................................ 94 Contenedores para Documentos Dinmicos .......................................................................... 95 FlowDocumentScrollViewer .................................................................................................... 95 FlowDocumentPageViewer ..................................................................................................... 95 FlowDocumentReader ............................................................................................................ 96 Formateando Documentos Dinmicos.................................................................................... 96 Elementos en Bloque .............................................................................................................. 96 List ........................................................................................................................................... 97 Tabla ....................................................................................................................................... 98 Section .................................................................................................................................... 99 BlockUIContainer .................................................................................................................... 99 Elementos en Lnea (Contenido dinmico) ........................................................................... 100 8

3- Documentos Fijos ............................................................................................................... 101 Definicin .............................................................................................................................. 101 PageContent ......................................................................................................................... 101 FixedPage ............................................................................................................................. 101 DocumentViewer ................................................................................................................... 102 4- Empaquetado e Impresin de Documentos ..................................................................... 104 Empaquetado ........................................................................................................................ 104 Empaquetar componentes .................................................................................................... 105 Documentos XPS (XPSDocument)....................................................................................... 105 XpsDocumentWriter .............................................................................................................. 105 Impresin de Documentos .................................................................................................... 106 MDULO 7: GRFICOS, ANIMACIONES Y MULTIMEDIA ................................................... 107 1- Grficos 2D .......................................................................................................................... 108 Dibujos y formas ................................................................................................................... 108 Shape .................................................................................................................................... 108 Propiedades de las formas ................................................................................................... 108 Drawing ................................................................................................................................. 109 Propiedad Clip ....................................................................................................................... 110 Brush ..................................................................................................................................... 110 2- Imgenes .............................................................................................................................. 112 Imgenes .............................................................................................................................. 112 Control Image........................................................................................................................ 112 Girar, Convertir y Recortar Imgenes ................................................................................... 113 Expandir imgenes ............................................................................................................... 114 Pintar con imgenes ............................................................................................................. 115 3- Grficos 3D .......................................................................................................................... 115 Viewport3D ............................................................................................................................ 115 Espacio de coordenadas 3D ................................................................................................. 116 Cmaras y proyecciones ...................................................................................................... 116 Elementos primitivos de modelo y malla............................................................................... 117 Materiales del Modelo ........................................................................................................... 118 Iluminar la escena ................................................................................................................. 118 Transformar modelos ............................................................................................................ 120 Animar modelos .................................................................................................................... 120 Transformaciones de Traslacin ........................................................................................... 121 Transformaciones de Escala ................................................................................................ 123 Transformaciones de Giro .................................................................................................... 125 4- Multimedia............................................................................................................................ 127 Media API .............................................................................................................................. 127 Modos Media Playback ......................................................................................................... 127 SoundPlayer .......................................................................................................................... 128 MDULO 8: CONFIGURACIN Y DISTRIBUCIN ................................................................ 129 1- Configuracin ...................................................................................................................... 130 Configurar Aplicaciones ........................................................................................................ 130 App.config ............................................................................................................................. 130 9

Recuperando informacin de app.config .............................................................................. 132 Almacenar informacin en app.config en run-time .............................................................. 132 2- Distribucin de Aplicaciones WPF .................................................................................... 132 XCopy ................................................................................................................................... 132 Microsoft Windows Installer .................................................................................................. 132 ClickOnce .............................................................................................................................. 133 Publicacin ClickOnce .......................................................................................................... 133 Como Publicar ....................................................................................................................... 134 Comparacin entre ClickOnce y Microsoft Windows Installer .............................................. 135 Links Relacionados ................................................................................................................. 137

10

Audiencia Este curso est orientado a aquellos profesionales o estudiantes que quieran adquirir los conocimientos y habilidades necesarias para desarrollarse como proveedor de software independiente. As mismo desarrolladores .NET (C#) que quieran incursionar en las nuevas tecnologas de .NET. Pre-requisitos Desarrolladores en Programacin .NET (C #) o bien personas que hayan aprobado el curso de MS Net Junior (160 hs) Duracin El curso tiene una duracin de 28 horas reloj con una carga horaria no superior a 12 horas semanales. Al Finalizar el curso Despus de completar este curso los alumnos sern capaces de: Construir un interfase de usuario en una aplicacin WPF Personalizar la apariencia de una aplicacin WPF Crear controles de usuario en una aplicacin WPF Enlazar controles a fuentes de datos Enlazar controles a colecciones Manejar documentos en aplicaciones WPF Trabajar con grficos y multimedia en aplicaciones WPF Configurar e instalar aplicaciones WPF

11

Mdulo 1

Introduccin a WPF

12

1- Introduccin
Definicin Windows Presentation Foundation (WPF) es un sistema de presentacin 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. El ncleo de WPF es un motor de representacin independiente de la resolucin y basado en vectores construido para aprovechar al mximo el hardware de grficos moderno. WPF ampla el ncleo con un completo conjunto de caractersticas de programacin de aplicaciones, entre las que se incluyen Lenguaje de marcado de aplicaciones extensible (XAML), controles, enlace de datos, diseo, grficos 2D y 3D, animacin, estilos, plantillas, documentos, multimedia, texto y tipografa. WPF se incluye en Microsoft .NET Framework, lo que permite crear aplicaciones que incorporen otros elementos de la biblioteca de clases de .NET Framework. Programar con WPF WPF constituye un subconjunto de tipos de .NET Framework, en su mayora ubicados en el espacio de nombres de System.Windows. Si ha creado previamente aplicaciones con .NET Framework mediante tecnologas administradas como ASP.NET y formularios Windows Forms, los conceptos fundamentales de la programacin en WPF debern resultarle familiares; crear instancias de clases, definir propiedades, llamar a mtodos y controlar eventos con el lenguaje de programacin de .NET Framework que prefiera, como C# o Visual Basic. Para admitir algunas de las funciones de WPF ms eficaces y simplificar la experiencia de programacin, WPF incluye construcciones de programacin adicionales que mejoran las propiedades y los eventos Cdigo de lenguaje marcado y cdigo subyacente WPF proporciona mejoras de programacin adicionales para el desarrollo de aplicaciones cliente de Windows. Una mejora evidente es la capacidad para programar una aplicacin mediante cdigo 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 aplicacin, y los lenguajes de programacin administrados (c#, visual Basic, etc.) para implementar su comportamiento. Esta separacin entre la apariencia y el comportamiento aporta las ventajas siguientes: Se reducen los costos de programacin y mantenimiento, al no estar el marcado especfico de la apariencia estrechamente relacionado con el cdigo especfico del comportamiento. La programacin es ms eficaz porque los diseadores pueden implementar la apariencia de una aplicacin al mismo tiempo que los programadores implementan su comportamiento. Se pueden utilizar varias herramientas de diseo para implementar y compartir el lenguaje marcado XAML, a fin de responder a los requisitos de los colaboradores de programacin de aplicaciones. Microsoft Expression Blend proporciona una experiencia apropiada para los diseadores, mientras que Visual Studio 2008 est dirigido a los programadores. La globalizacin y localizacin de las aplicaciones WPF se ha simplificado en gran medida.

XAML XAML es un lenguaje de marcado basado en XML que se utiliza para implementar la apariencia de una aplicacin mediante declaracin. Se suele utilizar para crear ventanas, cuadros de 13

dilogo, pginas y controles de usuario, as como para rellenarlos con controles, formas y grficos. Ejemplo: <Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" Title="Ventana con un Botn" Width="250" Height="100"> <Button Name="button">Presionar</Button> </Window> El cdigo XAML define una ventana y un botn mediante los elementos Window y Button, respectivamente. Cada elemento se configura con atributos o propiedades, como el atributo Title del elemento Window, para especificar el texto de la barra de ttulo de la ventana. En tiempo de ejecucin, WPF convierte los elementos y los atributos definidos en el marcado en instancias de clases de WPF. Puesto que XAML se basa en XML, la interfaz de usuario que se crea con este lenguaje se ensambla en una jerarqua de elementos anidados que se denomina rbol de elementos. El rbol de elementos proporciona una manera lgica e intuitiva de crear y administrar las interfases de usuario. Cdigo Subyacente El comportamiento principal de una aplicacin 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 botn) y llamar, en respuesta, a la lgica de negocios y de acceso a los datos. En WPF, este comportamiento se suele implementar en cdigo asociado al marcado. Este tipo de cdigo se denomina subyacente. En el ejemplo siguiente se muestran el cdigo subyacente y el marcado actualizado del ejemplo anterior. <Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" Title="Ventana con un Botn" Width="250" Height="100"> <Button Name="button" Click=button_Click>Presionar</Button> </Window> Cdigo subyacente: using System.Windows; namespace EjemploWFP { public partial class miEjemplo : Window { public void button_Click(object sender, RoutedEventArgs e) { MessageBox.Show("Probando Windows Presentation Foundation!"); } } } 14

Aplicaciones WPF Microsoft .NET Framework, System.Windows, as como el cdigo de lenguaje marcado y subyacente, constituyen la base de la experiencia de programacin de aplicaciones en WPF. Adems, WPF cuenta con caractersticas 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 aplicacin. El modelo de aplicacin admite la programacin 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 dilogo a los que se tiene acceso desde las barras de mens y las barras de herramientas. Aplicaciones hospedadas en explorador: Tambin denominadas Aplicaciones del explorador XAML (XBAPs XAML Browsers Applications, generan archivos con extensin xbap), puede crear pginas (Page) y funciones de pgina (PageFunction<T>) entre las que se puede navegar mediante hipervnculos (clases Hyperlink). Estas aplicaciones pueden hospedarse en Internet Explorer a partir de la versin 6.

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. An as, la mayora de las caractersticas de WPF se pueden ejecutar con seguridad desde las XBAPs.

2- Conceptos Bsicos
Controles En WPF, un control es un trmino general que se aplica a una categora de clases de WPF hospedadas en una ventana o una pgina, tienen una interfaz de usuario (UI) e implementa un comportamiento determinado. 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 administracin del enfoque y la posicin del mouse. A continuacin se muestra la lista de controles de WPF integrados. Botones: Button y RepeatButton. Cuadros de dilogo: OpenFileDialog, PrintDialog y SaveFileDialog. Entradas manuscritas digitales: InkCanvas y InkPresenter. Documentos: DocumentViewer, FlowDocumentPageViewer, FlowDocumentReader, FlowDocumentScrollViewer y StickyNoteControl. Entrada: TextBox, RichTextBox y PasswordBox. Diseo: 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. Mens: ContextMenu, Menu y ToolBar. Navegacin: Frame, Hyperlink, Page, NavigationWindow y TabControl. Seleccin: CheckBox, ComboBox, ListBox, TreeView y RadioButton, Slider. Informacin para el usuario: AccessText, Label, Popup, ProgressBar, StatusBar, TextBlock y ToolTip.

Diseo 15

Al crear una interfaz de usuario, se organizan los controles segn su ubicacin y tamao para crear un diseo. Un requisito fundamental de cualquier diseo es adaptarse a los cambios de tamao de la ventana y de configuracin de pantalla. En lugar de obligarle a escribir cdigo que adapte el diseo en estas circunstancias, WPF le proporciona un sistema de diseo extensible de primera clase. La base del sistema de diseo es la situacin relativa, que aumenta la capacidad de adaptacin a los cambios en la configuracin de las ventanas y de la pantalla. Adems, el sistema de diseo administra la negociacin entre los controles para determinar el diseo. La negociacin es un proceso de dos pasos: en primer lugar, el control indica a su elemento primario qu ubicacin y tamao necesita; en segundo lugar, el elemento primario indica al control de qu espacio dispone. El sistema de diseo se expone a los controles secundarios mediante las clases base de WPF. Para los diseos comunes, como son las cuadrculas, el apilamiento y el acoplamiento, WPF incluye varios controles de diseo: Canvas: los controles secundarios proporcionan su propio diseo. DockPanel: los controles secundarios se alinean con los bordes del panel. Grid: los controles secundarios se sitan 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 lnea en sentido horizontal o vertical. WrapPanel: los controles secundarios se sitan por orden de izquierda a derecha y se ajustan a la lnea siguiente cuando hay ms controles de los que caben en la lnea actual.

Enlace de Datos La mayora 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 tecnologas existentes, como Microsoft SQL Server y ADO.NET. Para simplificar la programacin de aplicaciones, WPF proporciona un motor de enlace de datos que realiza estos pasos automticamente. La unidad que constituye el ncleo 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). El motor de enlace de datos de WPF proporciona compatibilidad adicional que incluye validacin, ordenacin, filtrado y agrupacin. Adems, 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 estndar de WPF no es adecuada.

Grficos WPF presenta un conjunto extenso, escalable y flexible de caractersticas de grficos que aportan las ventajas siguientes: Grficos independientes de la resolucin e independientes del dispositivo. La unidad de medida bsica del sistema de grficos de WPF es el pxel independiente del dispositivo, que es 1/96 de pulgada, independientemente de la resolucin de pantalla real, y que proporciona la base para la representacin independiente de la resolucin y del dispositivo. Cada pxel independiente del dispositivo se escala automticamente para coincidir con el valor de puntos por pulgada (ppp) del sistema en que se representa. Precisin mejorada. El sistema de coordenadas de WPF se mide con nmeros de punto flotante de precisin doble, en lugar de precisin simple. Las transformaciones y los valores de opacidad tambin se expresan como doble precisin. WPF admite 16

tambin una amplia gama de colores (scRGB) y proporciona compatibilidad integrada para administrar las entradas desde espacios de color diferentes. Compatibilidad con grficos avanzados y animacin. WPF simplifica la programacin de grficos administrando automticamente las escenas de animacin. Aceleracin de hardware. El sistema de grficos de WPF saca partido del hardware de grficos para minimizar el uso de CPU.

Formas 2D WPF proporciona una biblioteca de formas 2D comunes dibujadas mediante vectores. Una funcin interesante de las formas es que no sirven nicamente para su presentacin; las formas implementan muchas de las caractersticas que cabe esperar de los controles, incluida la entrada de datos desde el teclado y el Mouse.

Geometras 2D Las formas 2D proporcionadas por WPF abarcan el conjunto estndar de formas bsicas. Sin embargo, puede que sea preciso crear formas personalizadas para facilitar el diseo de una interfaz de usuario personalizada. Para este fin, WPF proporciona las geometras. Estas permiten 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 comprobacin de visitas y la representacin de datos de grficos 2D.

Efectos 2D Un subconjunto de las funciones 2D de WPF son los efectos visuales, tales como degradados, mapas de bits, dibujos, pintar con vdeos, rotacin, ajuste de escala y sesgo. Todas ellas se aplican mediante pinceles.

Representaciones 3D WPF tambin incluye funciones de representacin 3D que se integran con los grficos 2D para permitir la creacin de interfases de usuarios ms importantes.

Animaciones La compatibilidad de WPF con la animacin permite hacer que los controles crezcan, tiemblen, giren o se desvanezcan, crear transiciones de pgina interesante, y mucho ms. Puede animar la mayora de las clases de WPF, incluso las personalizadas.

Multimedia Una manera de mostrar un contenido enriquecido es utilizar medios audiovisuales (multimedia). WPF proporciona compatibilidad especial con imgenes, vdeo y audio. Imgenes: Las imgenes estn presentes en la mayora de las aplicaciones y WPF proporciona varias maneras de utilizarlas. Video y Audio: El control MediaElement es capaz de reproducir vdeo y audio y presenta la flexibilidad suficiente para constituir la base de un reproductor multimedia personalizado. El marcado XAML siguiente implementa un reproductor multimedia. 17

Texto y Tipografa Para facilitar una representacin de texto de gran calidad, WPF ofrece las caractersticas siguientes: Compatibilidad con fuentes OpenType. Mejoras de ClearType. Alto rendimiento que saca partido de la aceleracin de hardware. Integracin de texto con multimedia, grficos y animacin. Compatibilidad con fuentes internacionales y mecanismos de reserva.

Documentos WPF permite trabajar de forma nativa con tres tipos de documentos: documentos dinmicos, documentos fijos y documentos de XML Paper Specification (XPS). WPF proporciona tambin servicios para crear, ver, administrar, anotar, empaquetar e imprimir documentos. Documentos dinmicos: Los documentos dinmicos se han diseado para optimizar su presentacin y legibilidad ajustando dinmicamente su contenido y modificando su flujo cuando se producen cambios en el tamao de la ventana y la configuracin de pantalla. Documentos Fijos: Los documentos fijos estn destinados a aplicaciones que requieren una presentacin con representacin fiel (lo que se ve es lo que se obtiene, o WYSIWYG, en sus siglas en ingls) precisa, especialmente por lo que respecta a su impresin. Los usos tpicos para los documentos fijos incluyen la creacin de publicaciones, el procesamiento de textos y el diseo de formularios, donde es vital que se respete el diseo de pgina original. Los documentos fijos conservan la organizacin precisa de su contenido de una manera independiente del dispositivo. El diseo permanece inalterado en todos los casos, aunque la calidad del documento vara segn las funciones de cada dispositivo. 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 bsicamente es una representacin en forma de pgina de documentos electrnicos. XPS es un formato de documento abierto habilitado para varios exploradores y diseado para facilitar la creacin, el uso compartido, la impresin y el almacenamiento de documentos paginados.

Anotaciones Las anotaciones son notas o comentarios que se agregan a los documentos para marcar la informacin o resaltar elementos de inters, a fin de consultarlos ms adelante. Aunque escribir notas en documentos impresos es fcil, la posibilidad de "escribir" notas en los documentos electrnicos con frecuencia es limitada o no est disponible en absoluto. Sin embargo, en WPF se proporciona un sistema de anotaciones que admite la insercin de notas rpidas y el resaltado.

Empaquetado Las APISystem.IO.Packaging de WPF permiten que las aplicaciones organicen los datos, el contenido y los recursos en un nico documento ZIP porttil, sencillo de distribuir y de fcil 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. Tambin puede cifrar los paquetes mediante la administracin de derechos para restringir el acceso a la informacin protegida.

Impresin 18

Microsoft .NET Framework incluye un subsistema de impresin al que WPF aporta, adems, compatibilidad con el control de sistemas de impresin mejorados. Las mejoras de impresin incluyen las siguientes: Instalacin en tiempo real de servidores de impresin y colas remotos. Deteccin dinmica de funciones de impresora. Configuracin dinmica de opciones de impresin. Modificacin del enrutamiento y las prioridades de los trabajos de impresin. Los documentos XPS presenta, adems, una mejora fundamental del rendimiento. La ruta de acceso de Interfaz de dispositivo grfico de Microsoft Windows (GDI) de impresin suele requerir dos conversiones: La primera conversin del documento a un formato de procesador de impresin, como Metarchivo mejorado (EMF). Una segunda conversin al lenguaje de descripcin de pginas 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 impresin y un lenguaje de descripcin de pginas. Esta compatibilidad ayuda a reducir el tamao del archivo de cola y las cargas de las impresoras integradas en red.

Personalizacin Para simplificar la organizacin de los controles en una interfase de usuario y asegurarse de que la organizacin se conserve aunque se modifiquen el tamao de la ventana y la configuracin de pantalla, se utiliza el sistema de diseo de WPF. Dado que la mayora de las aplicaciones permiten a los usuarios interactuar con los datos, los enlaces de datos se utilizan para reducir el trabajo de integracin de la interfaz de usuario con esos datos. A fin de mejorar la apariencia visual de la aplicacin, se utiliza toda la gama de grficos, animacin y multimedia que WPF proporciona. Por ltimo, si la aplicacin funciona a travs de texto y documentos, puede utilizar las funciones de tipografa, documentos, anotacin, empaquetado e impresin 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 aplicacin. Es posible que los datos no se muestren del modo ms 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 aplicacin. En muchos aspectos, una tecnologa de presentacin requiere la extensibilidad visual tanto como cualquier otro tipo de extensibilidad. Por esta razn, WPF proporciona gran variedad de mecanismos para la creacin de experiencias de usuario nicas, incluido un modelo de contenido enriquecido para los controles, estilos, desencadenadores, plantillas de controles y datos, estilos, recursos de la interfaz de usuario, temas y mscaras. Modelo de Contenido: El propsito principal de la mayora de los controles de WPF es mostrar contenido. En WPF, el tipo y nmero 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. 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 diseo, texto, imgenes y formas. Desencadenadores (Triggers): Aunque el propsito principal del marcado XAML es implementar la apariencia de una aplicacin, tambin puede utilizar XAML para implementar algunos aspectos del comportamiento de una aplicacin. Un ejemplo de 19

ello es el uso de desencadenadores para cambiar la apariencia de una aplicacin de acuerdo con las interacciones con el usuario. Plantillas de Control: Las UIs predeterminadas para los controles de WPF suelen construirse a partir de otros controles y formas. A veces, la apariencia predeterminada de un control puede ser incongruente con la apariencia global de una aplicacin. En este caso, puede utilizar una plantilla de control ControlTemplate para cambiar la apariencia de la interfase de usuario del control sin modificar su contenido ni su comportamiento. Plantilla 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. Estilos: Los estilos permiten a los programadores y diseadores normalizar un aspecto determinado de sus productos. WPF proporciona un modelo de estilo slido, que es la base del elemento Style. Recursos: Los controles de una aplicacin 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 la interfase de usuario (UI) para encapsular estos recursos en una ubicacin nica y poder reutilizarlos. Temas y Mscaras: Desde una perspectiva visual, un tema define la apariencia global de Windows y de las aplicaciones que se ejecutan dentro del mismo. La apariencia definida por un tema establece la apariencia predeterminada de una aplicacin WPF. Sin embargo, WPF no se integra directamente con los temas de Windows. Como la apariencia de WPF se define mediante plantillas, WPF incluye una plantilla para cada uno de los temas conocidos de Windows, como Aero (Windows Vista), Clsico (Microsoft Windows 2000), etc. Estos temas estn empaquetados en diccionarios de recursos que se resuelven cuando no se encuentran los recursos correspondientes en una aplicacin. Por otro lado, la experiencia del usuario para algunas aplicaciones no procede necesariamente de los temas estndar. Tales UIs tienden a proporcionar temas personalizados, especficos de cada aplicacin. Se denominan mscaras, y las aplicaciones con mscaras suelen proporcionar enlaces que permiten a los usuarios personalizar diversos aspectos de la mscara. Controles Personalizados: Aunque WPF proporciona una amplsima compatibilidad con funciones de personalizacin, puede encontrar situaciones en que los controles existentes de WPF no satisfagan las necesidades de la aplicacin o de los usuarios. WPF permite crear controles.

3- Eventos y Comandos
Informacin general sobre Eventos Enrutados En los primeros pasos con WPF, lo ms probable es que use eventos enrutados an sin saber que los est usando. Por ejemplo, si agrega un botn a una ventana en el diseador de Visual Studio, modifica el nombre a miBoton y despus hacer doble clic sobre l, el evento Click se conectar al marcado XAML y se agregar un controlador de eventos para este evento al cdigo que hay tras la clase Window. Esto es lo mismo que la conexin de eventos en Windows Forms y ASP.NET. En concreto, en el marcado XAML para el botn, terminar por tener un cdigo parecido a este: <Button Name=" miBoton " Click="miBoton_Click">Click Me</Button>

20

La declaracin de XAML para incorporar un evento es parecida a una asignacin de propiedad en XAML, pero el resultado es un enlace de evento normal en el objeto que especific el controlador de eventos. Si cambia la ventana al editor de cdigo ver lo siguiente: private void myButton_Click(object sender, RoutedEventArgs e) { } Esto es igual a cualquier otra conexin de evento .NET, se tiene un delegado explcitamente declarado y enlazado a un evento de un objeto, y el delegado apunta a un mtodo de control. El nico indicio de que se estn usando eventos enrutados es el tipo del argumento de evento para el evento Click, que es RoutedEventArgs. Entonces, qu tienen de especial los eventos enrutados? Un evento enrutado es un tipo de evento que puede invocar controladores o varios agentes de escucha en un rbol de elementos, en lugar de simplemente en el objeto que lo desencaden. Para comprender mejor esta definicin, necesitar antes comprender el modelo de composicin elemental de WPF.

rboles de elementos WPF Si empieza con una ventana nueva en un proyecto y arrastra un botn en la ventana del diseador, terminar con un rbol de elementos en el XAML parecido a ste (los atributos se omitieron para mejorar la claridad): <Window> <Grid> <Button/> </Grid> </Window> Cada uno de estos elementos representa una instancia en tiempo de ejecucin de un tipo .NET correspondiente y la jerarqua declarada de elementos forma lo que se denomina un rbol lgico. Adems, muchos controles de WPF son a su vez contenedores, lo que significa que pueden tener elementos secundarios. Por ejemplo, un Button puede tener un elemento secundario complejo como contenido. El rbol lgico se podra expandir como se muestra aqu: <Window> <Grid> <Button> <StackPanel> <Image/> <TextBlock/> </StackPanel> </Button> </Grid> </Window> Como puede imaginar, el rbol podra contener varias ramas y el rbol lgico puede crecer considerablemente en complejidad. Lo ms importante a tener en cuenta sobre los elementos WPF del rbol lgico es que lo que se ve no es realmente lo que se obtiene en tiempo de ejecucin. Cada uno de esos elementos suele ampliarse hasta formar un rbol ms complejo de elementos visuales en tiempo de ejecucin. Cuando hago clic en mi botn, puede que en realidad no est haciendo clic en el elemento Button; puedo estar haciendo clic en un elemento secundario del rbol visual, posiblemente incluso uno que no se muestre en mi rbol lgico (como ButtonChrome). Por ejemplo, digamos que hago clic sobre la imagen que contiene mi botn. En realidad, el clic se manifiesta 21

inicialmente como un evento de MouseLeftButtonDown incluido dentro del elemento Image. Pero de alguna forma esto hay que trasladarlo a un evento Click al nivel del Button. Es aqu donde entra en juego el enrutamiento en eventos.

Enrutamiento de eventos Es importante entender un poco los rboles lgicos y visuales porque los eventos enrutados se enrutan principalmente segn el rbol visual. Los eventos enrutados admiten una RoutingStrategy que puede ser Bubble, Tunnel o Direct. Bubble es la ms comn y significa que un evento se propagar hacia la parte superior del rbol visual a partir del elemento origen hasta que se controle o alcance el elemento raz. Esto le permite controlar un evento de un objeto an ms arriba de la jerarqua de elementos desde el elemento origen. Por ejemplo, se podra adjuntar un controlador Button.Click en elemento Grid que lo contiene en vez de directamente en el propio botn. Tunnel: Los eventos Tunnel van en direccin contraria, se inician en el elemento raz y van bajando por el rbol de elementos hasta que se controlan o alcanzan el elemento origen para el evento. Esto permite que los elementos precedentes intercepten el evento y lo controlen antes de que alcance el elemento origen. Los eventos Tunnel usan como prefijo de sus nombres Preview como convencin (por ejemplo, PreviewMouseDown). Direct: Los eventos directos se comportan como eventos normales de .NET Framework. El nico controlador posible para el evento es un delegado que se enlaza al evento.

Eventos enrutados y composicin Vayamos paso a paso para ver cmo el evento Button.Click se produce y regresa a casa, ya que es importante. Como he mencionado anteriormente, un usuario iniciar un evento Click con un evento MouseLeftButtonDown en algn elemento secundario del rbol visual del Button, como en el caso de Image en el ejemplo anterior. Cuando se produce el evento MouseLeftButtonDown dentro del elemento Image, se inicia un evento PreviewMouseLeftButtonDown en la raz y profundiza hacia Image. Si ningunos de los controladores establecen la marca Handled en verdadero para el evento de vista previa, se inicia la propagacin del evento MouseLeftButtonDown desde el elemento Image hasta que 22

llega a Button. El botn controla ese evento, establece la marca Handled en verdadero y acciona su propio evento Click. Las implicaciones son bastante eficaces. Por ejemplo, si elijo reemplazar la apariencia predeterminada del botn aplicando una plantilla de control que contenga un elemento Ellipse, no tengo que hacer nada para garantizar que los clics hechos fuera de Ellipse no accionen el evento Click. Los clics que quedan justo fuera del borde de Ellipse seguirn estando dentro de los lmites rectangulares de mi botn, pero Ellipse tiene su propia deteccin de aciertos para MouseLeftButtonDown, cosa que no ocurre para las partes vacas del botn que estn fuera de Ellipse. As que slo los clics que se hacen dentro de Ellipse accionan el evento MouseLeftButtonDown. Sigue estando controlado por la clase Button a la que se adjunta la plantilla, as que se obtendr el comportamiento previsible incluso del botn personalizado. Esto tambin es un concepto muy importante que recordar al escribir sus propios controles compuestos personalizados, porque lo ms probable es que necesite hacer cosas parecidas a las que hace Button para administrar eventos de elementos secundarios que se coloquen dentro de su control.

Eventos adjuntos Los eventos adjuntos son eventos enrutados que admiten un enlace XAML sobre elementos distintos del tipo en el que se declara el evento. Por ejemplo, si desea que el elemento Grid est atento al paso de un evento Button.Click, slo tendra que enlazarlo de esta forma: <Grid Button.Click="myButton_Click"> <Button Name="myButton" >Presionar</Button> </Grid> Los eventos adjuntos slo dan un poco ms de flexibilidad en los sitios donde conecta sus controladores de eventos. Pero si los elementos estn contenidos en la misma clase (como en este ejemplo), puede no resultar aparente qu diferencia hay porque, en ambos casos, el mtodo de control sigue siendo slo un mtodo de la clase Window.

Informacin general sobre Comandos enrutados Los comandos enrutados de WPF ofrecen un mecanismo especfico para enlazar controles de IU como botones de barra de herramientas y elementos de men a controladores, sin tener que realizar muchos emparejamientos integrados ni cdigo repetitivo en la aplicacin. Los comandos enrutados ofrecen tres cosas importantes adems del control normal de eventos: Los elementos origen del comando enrutado (invocadores) pueden estar desconectados de los destinos de comandos (controladores), no es necesario que haya referencias directas entre ellos, como ocurrira si estuvieran vinculados por un controlador de eventos. Los comandos enrutados habilitarn o deshabilitarn todos los controles de IU asociados cuando el controlador indica que el comando est deshabilitado. Los comandos enrutados le permiten asociar mtodos abreviados de teclado y otras formas de movimientos de entrada (movimientos de lpiz ptico, por ejemplo) como otra manera de invocar el comando. Adems, una variedad especfica del comando enrutado (la clase RoutedUICommand) agrega la capacidad de definir una sola propiedad Text para usarla como indicaciones de texto de cualquier control que sea invocador para el comando. La propiedad Text tambin se puede localizar ms fcilmente que visitando todos los controles del invocador asociado. Para declarar un comando en un invocador, slo tiene que establecer una propiedad Command sobre el control que iniciar el comando: 23

<Button Command="ApplicationCommands.Save">Guardar</Button> La propiedad Command la admiten MenuItem, Button, RadioButton, Checkbox, Hyperlink y otros controles. Para concretar y ver rpidamente las ventajas de los comandos enrutados, veamos un ejemplo sencillo. En la siguiente figura se puede ver una IU con dos TextBoxs y un botn de barra de herramientas para realizar una accin Cortar sobre el texto de los cuadros de texto.

Para poder conectar esto usando eventos, necesitara definir un controlador Click para el botn de la barra de herramientas y ese cdigo necesitara hacer referencia a los dos cuadros de texto. Tendra que determinar qu cuadro de texto tiene el foco y llamar a operaciones apropiadas del portapapeles segn la seleccin del texto en el control. Tambin tendra que preocuparse de habilitar y deshabilitar el botn de la barra de herramientas segn donde est el foco y si se seleccion algo en el cuadro de texto. Esto generara un cdigo complejo y desordenado. Con comandos, lo nico que hay que hacer es establecer la propiedad Command del botn de la barra de herramientas en el comando ApplicationCommands.Cut que est definido en WPF y ya est listo. <StackPanel> <ToolBar DockPanel.Dock="Top" Height="25"> <Button Command="ApplicationCommands.Cut"> <Image Source="cut.ico"/> </Button> </ToolBar> <TextBox Name="txt1" Width="100" Height ="23"></TextBox> <TextBox Name="txt2" Width="100" Height ="23"></TextBox> </StackPanel> Ahora podra ejecutar la aplicacin y comprobar que el botn de la barra de herramientas est inicialmente deshabilitado. Despus de seleccionar texto en uno de los cuadros de texto, el botn de la barra de herramientas pasa a estar habilitado y, si se hace clic en l, el texto se corta y pasa al portapapeles. Y funcionara para cualquier TextBox de cualquier lugar de la IU. Lo que sucede aqu es que la implementacin de la clase TextBox tiene un enlace de comandos integrado para el comando Cut y encapsula automticamente el control del portapapeles para ese comando (adems de Copy y Paste). Pero, cmo se invoca solamente el comando en el cuadro de texto enfocado, y cmo llega el mensaje al cuadro de texto para decirle que controle el comando? Aqu es donde entra en juego el enrutamiento de comandos. 24

Enrutamiento de comandos La diferencia entre comandos enrutados y eventos enrutados es la forma en que el comando se dirige desde el invocador del comando al controlador del comando. Concretamente, los eventos enrutados se usan internamente para dirigir mensajes entre los invocadores y los controladores de comandos (mediante el enlace de comandos que se engancha en el rbol visual). Aqu podra haber una relacin de varios a varios, pero slo un controlador de comando estar realmente activo en cada momento. El controlador de comandos activo lo determina una combinacin de las posiciones del invocador y del administrador de comandos en el rbol visual, y de la posicin del foco en la interfase de usuario. Los eventos enrutados se usan para llamar al controlador de comandos activo para preguntarle si se debe habilitar el comando, as como para invocar al controlador de mtodo Execute del controlador de comandos. Generalmente, un invocador de comandos busca un enlace de comandos entre su propia ubicacin en el rbol visual y la raz del rbol visual. Si encuentra uno, el controlador de comandos enlazado determinar si el comando est habilitado y se llamar cuando se invoque el comando. Si el comando est conectado a un control de una barra de herramientas o de un men, entonces se ejecuta lgica adicional que tambin examina la ruta de acceso del rbol visual desde la raz al elemento del foco buscando un enlace de comando.

Definicin de comandos Existen cinco clases de comandos integradas en WPF: ApplicationCommands: Close, Cut, Copy, Paste, Save, Print NavigationCommands: BrowseForward, BrowseBack, Zoom, Search EditingCommands: AlignXXX, MoveXXX, SelectXXX MediaCommands: Play, Pause, NextTrack, IncreaseVolume, Record, Stop ComponentCommands: MoveXXX, SelectXXX, ScrollXXX, ExtendSelectionXXX XXX indica diversas operaciones como MoveNext y MovePrevious. Los comandos de cada clase estn definidos como propiedades para que pueda conectarlos fcilmente. Tambin puede usar estos comandos con una notacin abreviada <Button Command="Save">Save</Button>

Desafos de los comandos enrutados Los comandos enrutados funcionan bien en escenarios de interfases de usuario sencillas, conectando barras de herramientas y elementos de men, y controlando esas cosas que estn emparejadas intrnsecamente al foco del teclado (como las operaciones con el portapapeles). Sin embargo, donde los comandos enrutados se muestran insuficientes, es cuando se empieza a crear interfases de usuario complejas, donde la lgica del control de comandos est en el cdigo de soporte para las definiciones de vista y los invocadores de comando no siempre estn dentro de una barra de herramientas o de un men. El problema que surge al trabajar de este modo es que la habilitacin y el control de lgica para un comando puede no formar parte del rbol visual directamente; en su lugar puede estar situada en un presentador o en un modelo de presentacin. Adems, el estado que determina si el comando debe habilitarse puede no tener relacin con la situacin de los invocadores de comandos y las vistas en el rbol visual. Tambin puede encontrar casos donde haya ms de un controlador vlido al mismo tiempo para un comando particular. Para evitar los problemas potenciales de la ubicacin del rbol visual con comandos enrutados, necesitar simplificar las cosas. Normalmente necesitar asegurarse de que los controladores de comando estn en el mismo elemento o en niveles superiores del rbol visual del elemento que invocar el comando. 25

Mdulo 2

Creando Aplicaciones WPF

26

1- Crear una aplicacin WFP


Aplicacin WPF Dentro de Visual Studio: En el men Archivo, haga clic en Nuevo proyecto. Aparecer el cuadro de dilogo de Nuevo proyecto. Seleccione el lenguaje y elija Aplicacin WPF. Cambie el nombre de la aplicacin. Haga clic en Aceptar.

Se crear una nueva carpeta para el proyecto con el nombre del proyecto y, a continuacin, mostrar el nuevo formulario WPF titulado Window1 en la vista Diseador. Dentro de esta vista se puede trabajar el formulario de forma similar al de las aplicaciones Windows. Arrastre controles y modifique sus propiedades usando la ventana de propiedades. Escriba los atajadores de eventos en el archivo .xaml.cs o .xaml.vb segn el lenguaje seleccionado. La ventana de WPF que se ve en la vista Diseador es una representacin visual de la ventana que se abrir al iniciar la aplicacin. En la vista Diseador, puede arrastrar diversos controles desde el Cuadro de herramientas hasta la ventana WPF. Despus de haber colocado un control a la ventana de WPF, Visual C# crea automticamente cdigo que har que el control se site apropiadamente cuando se ejecute el programa.

27

Clase Window Permite crear, configurar, mostrar y administrar la duracin de las ventanas y los cuadros de dilogo. El punto de interaccin entre el usuario y una aplicacin independiente es una ventana. Una ventana de WPF se compone de dos reas distintas: Un rea no cliente, que hospeda los elementos grficos de las ventanas, incluidos un icono, ttulo, men del sistema, botn para minimizar, botn para maximizar, botn para restablecer, botn para cerrar y un borde. Un rea cliente, que hospeda el contenido especfico de la aplicacin. <Window x:Class="AplWPF.Principal" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Principal" Height="500" Width="500" WindowStyle="ThreeDBorderWindow" ResizeMode="CanResize" ShowInTaskbar="True" WindowState="Maximized">

Configurar la ventana de inicio El archivo App.xaml y el archivo de cdigo subyacente correspondiente se crean de forma predeterminada en un proyecto WPF. Este archivo contiene recursos de nivel de aplicacin que pueden ser usados en cualquier documento de la aplicacin. Dentro de este archivo se implementa la clase Application. La ventana de inicio se establece a travs de la propiedad StartupUri. <Application x:Class="WpfCSharp.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" StartupUri="Principal.xaml"> 28

<Application.Resources> </Application.Resources> </Application>

Propiedades de la Clase Window AllowsTransparency: Obtiene o establece un valor que indica si se puede ajustar la opacidad del formulario Background: Obtiene o establece un pincel (Brush) que describe el fondo de un control. BorderBrush: Obtiene o establece un pincel (Brush) que describe el fondo del borde de un control. BorderThickNess: Obtiene o establece el grosor del borde de un control. Cursor: Obtiene o establece el cursor que se muestra cuando el puntero del mouse se sita sobre este elemento. Foreground: Obtiene o establece un pincel (Brush) que describe el color de primer plano, generalmente la letra. Height: Obtiene o establece el alto sugerido del elemento, expresados en unidades independientes de dispositivo (1/96 de pulgada por unidad). Icon: Obtiene o establece el icono de una ventana. IsEnabled: Obtiene o establece si la ventana permite recibir entradas del usuario. Left: Obtiene o establece la posicin del borde izquierdo de la ventana con respecto al escritorio. ResizeMode: Obtiene o establece el modo de cambio de tamao. ShowInTaskBar: Obtiene o establece un valor que indica si la ventana tiene un botn de barra de tareas. SizeToContent: Obtiene o establece un valor que indica si una ventana ajustar automticamente su tamao al de su contenido. Title: Obtiene o establece el ttulo de una ventana. Top: Obtiene o establece la posicin del borde superior de la ventana con respecto al escritorio. TopMost: Obtiene o establece un valor que indica si una ventana aparece en el punto ms alto en el orden Z. Width: Obtiene o establece el ancho del elemento, expresados en unidades independientes de dispositivo (1/96 de pulgada por unidad). WindowStartupLocation: Obtiene o establece la posicin de la ventana cuando se muestra por primera vez. WindowState: Obtiene o establece un valor que indica si una ventana est restaurada, minimizada o maximizada. WindowStyle: Obtiene o establece el estilo de borde de una ventana.

Controles WPF y su equivalente con Controles Windows Forms Windows Forms Button CheckBox CheckedListBox ColorDialog WPF Button CheckBox ListBox Compuestos Comentarios

29

ComboBox ContextMenuStrip DataGridView

ComboBox ContextMenu Algunas funcionalidades de DataGridView se pueden reproducir usando los controles ListView y GridView.

DateTimePicker ErrorProvider FlowLayoutPanel FolderBrowserDialog FontDialog Form GroupBox HelpProvider Window GroupBox No tiene ayuda con F1. Se puede reemplazar esta funcionalidad con ToolTips WrapPanel o StackPanel

ImageList Label LinkLabel ListBox ListView MaskedTextBox MenuStrip MonthCalendar NotifyIcon NumericUpDown OpenFileDialog PageSetupDialog Panel Canvas TextBox y dos RepeatButton OpenFileDialog Menu ListBox ListView Solo contiene la vista de detalle en formato de solo. Label Se puede utilizar la clase Hyperlink.

30

PictureBox PrintDialog PrintDocument PrintPreviewControl PrintPreviewDialog ProgressBar RadioButton RichTextBox SaveFileDialog SoundPlayer SplitContainer StatusStrip TabControl TableLayoutPanel TextBox Timer ToolStrip ToolTip TrackBar TreeView WebBrowser

Image PrintDialog

DocumentViewer

ProgressBar RadioButton RichTextBox SaveFileDialog MediaPlayer GridSplitter StatusBar TabControl Grid TextBox DispatcherTimer ToolBar ToolTip Slider TreeView Frame, System.Windows.Controls.WebBr owser The Frame control can host HTML pages.

Controladores de Eventos Para crear un controlador de eventos se puede hacer doble clic sobre el control. De esta manera se crea el atajador del evento predeterminado de un control. Tambin puede agregarse como atributo escribiendo sobre el editor XAML. Al escribir el nombre del evento o seleccionarlo de la lista de ayuda aparecer una opcin <Nuevo 31

Controlador de Eventos> y el nombre de procedimientos posibles de ser seleccionados teniendo en cuenta la firma del atajador del evento seleccionado. El nombre predeterminado del atajador del evento ser NombreObjeto_Evento. El controlador de eventos se escribir en la clase asociada al formulario. Todas las libreras del Framework de .Net esta disponible para ser usada en este tipo de aplicaciones.

Recursos WPF provee recursos como una forma simple de reusar objetos y valores definidos. Se pueden crear recursos en XAML o por cdigo. Todos los elementos de nivel FrameWork tienen la propiedad Resources, aunque generalmente se los usa en elementos de tipo raz como Window. Los recursos deben contener una identificacin nica. Esta se declara usando x:Key. Generalmente la clave se la declara como carcter (string), aunque puede ser declarada usando otros tipos de datos. <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>

Recursos Estticos y Dinmicos Los recursos pueden ser referenciados en forma esttica o dinmica. Esto se hace usando StaticResource o DynamicResource y el nombre del recurso que se est referenciando. La 32

referencia esttica procesa la clave buscando el valor en todos los recursos disponibles, esto ocurre durante la carga del proceso. En cambio la referencia dinmica procesa la clave creando una expresin que permanece sin ser evaluada hasta el momento de la ejecucin, durante la ejecucin evala la expresin y devuelve el valor. Cuando se va a crear una referencia a un recurso, las siguientes consideraciones deberan tenerse en cuenta para elegir cual de las dos opciones va a usarse: Donde est creado el recurso, si es un recurso de ventana, de aplicacin, de control, etc. La funcionalidad de la aplicacin El comportamiento del recurso Cuando elegir StaticResource: La mayora de los recursos son de ventana o aplicacin. Los recursos no son re evaluados durante la ejecucin mejorando la performance. Se est estableciendo alguna propiedad del objeto en Freezable Se estn creando recursos que sern compilados en una dll aparte. Se estn definiendo recursos que van a ser usados en Temas Se estn usando recursos con muchas propiedades de dependencia. Cuando elegir DynamicResource: El valor del recurso depende de una condicin que solo se conoce durante la ejecucin. Se estn creando o referenciando Temas para un control personalizado Se est intentando ajustar el contenido de ResourceDictionary Cuando se usan recursos compilados Cuando se referencia recursos pesados y el uso de ese recurso no es inmediato, o sea no se usa durante la carga de la ventana. Los recursos estticos se cargan con la carga de la ventana, en cambio los dinmicos cuando se necesitan Se aplican recursos a elemento que dependen de elementos padres. Al cambiar el elemento padre es posible que sea necesario cambiar el objeto hijo tambin. <Button Background="{StaticResource MyBrush}"/> <Ellipse Fill="{StaticResource MyBrush}"/>

2- Controles de Diseo
Sistema de Diseo de Interfase de Usuario El trmino diseo describe el proceso de medir y organizar los integrantes de la coleccin Children de un elemento contenedor y, a continuacin, dibujarlos en la pantalla. Se trata de un proceso intensivo y, cuanto mayor es la coleccin Children, mayor es el nmero de clculos realizados. Tambin se puede incluir mayor complejidad segn el comportamiento de diseo definido por el elemento contenedor que posee la coleccin. Un diseo relativamente sencillo, como Canvas, puede producir un rendimiento excelente si no se requiere un Panel ms complejo como Grid. Cada vez que un elemento secundario cambia su posicin, tiene el potencial de desencadenar un nuevo paso del sistema de diseo. Como a tal, es importante entender los eventos que pueden invocar el sistema del diseo, puesto que la invocacin innecesaria puede deteriorar el rendimiento de la aplicacin. En su versin ms simple, el diseo es un sistema recursivo que conduce a la configuracin del tamao, posicin y representacin de un elemento en la pantalla. El sistema de diseo completa dos pasos por cada miembro de la coleccin Children: un paso de medida y un paso de organizacin. Se trata de la serie de eventos que se producen cada vez que se invoca el sistema de diseo. 33

Un elemento secundario comienza el proceso de diseo midiendo, en primer lugar, propiedades bsicas. Se evalan las propiedades de tamao, como Width, Height y Margin. Se aplica la lgica concreta del contenedor, como la direccin de Dock o la orientacin (Orientation) de apilado. El contenido se organiza despus de medir todos los elementos secundarios. Se dibuja la coleccin Children en la pantalla. Se invoca el proceso de nuevo si se agregan Children adicionales a la coleccin. Al pensar en el diseo de una aplicacin en Windows Presentation Foundation (WPF), es importante entender el rectngulo de seleccin que rodea todos los elementos. Esta abstraccin ayuda a comprender el comportamiento del sistema de diseo. Cada elemento utilizado por el sistema de diseo se puede considerar como un rectngulo que se inserta en una particin del diseo. El sistema, calculando el espacio de pantalla disponible, determina el tamao de ese rectngulo, el tamao de cualquier restriccin, las propiedades especficas del diseo, como el margen y el relleno, y el comportamiento individual del elemento primario. Al procesar estos datos, el sistema puede calcular la posicin de todos los elementos secundarios de un contenedor determinado. Es importante recordar que las caractersticas de tamao definidas en el elemento primario (como Border) afectan a sus elementos secundarios. Cuando se representa el contenido de un objeto Window, se invoca el sistema del diseo automticamente. Para mostrar el contenido, el Content de la ventana debe definir un panel raz que sirve para definir un marco que permite organizar los miembros de Children en la pantalla. A continuacin se detallan los controles disponibles como paneles o contenedores.

Border Dibuja un borde, un fondo o ambos alrededor de otro elemento. En el siguiente ejemplo se muestra un control Border que contiene un CheckBox. <Border Background="LightBlue" BorderBrush="Black" BorderThickness="2" CornerRadius="50" Padding="5" Height="36" VerticalAlignment="Top" Margin="100,44,116,0"> <CheckBox Name="Prueba" IsChecked="True" >Prueba</CheckBox> </Border>

Canvas Define un rea en la que pueden colocarse explcitamente los elementos secundarios utilizando las coordenadas relativas al rea del control Canvas. Canvas es el nico elemento del panel que no tiene ninguna caracterstica de diseo inherente. Tiene las propiedades predeterminadas Height y Width de cero. Siempre se da a los elementos secundarios de Canvas el tamao mximo que requieren. Como resultado, la alineacin vertical y horizontal no tiene ningn efecto en un control Canvas. Canvas es un control de diseo de nivel superior que puede utilizarse para la colocacin absoluta del contenido secundario. En el siguiente ejemplo se muestra un control Canvas con dos TextBlock contenidos. El uso de las propiedades Canvas.Top y Canvas.Left permite posicionar los controles contenidos. 34

<Canvas Background="LightSteelBlue"> <TextBlock FontSize="14" Canvas.Top="10" Canvas.Left="5">Hola Mundo!</TextBlock> <TextBlock FontSize="22" Canvas.Top="25" Canvas.Left="35">Hola</TextBlock> </Canvas>

DockPanel Define un rea en la que se pueden organizar horizontalmente o verticalmente los elementos secundarios, uno respecto al otro. La posicin de los elementos secundarios de un control DockPanel en la pantalla est determinada por la propiedad Dock de los elementos secundarios respectivos y el orden relativo de estos elementos secundarios en DockPanel. Por tanto, un conjunto de elementos secundarios con los mismos valores de la propiedad Dock se puede organizar de forma diferente en la pantalla dependiendo del orden de estos elementos secundarios dentro del DockPanel. La clasificacin de los elementos secundarios afecta a la posicin porque DockPanel recorre en iteracin sus elementos secundarios en orden, y establece la posicin de cada elemento en funcin del espacio restante. El mtodo SetDock cambia la posicin de un elemento respecto a otros elementos del mismo contenedor. Las propiedades de alineacin, como HorizontalAlignment, cambian la posicin de un elemento respecto a su elemento principal. Si establece la propiedad LastChildFill en true, que es el valor predeterminado, el ltimo elemento secundario de DockPanel rellena siempre el espacio restante, sin tener en cuenta ningn valor que se haya establecido en este elemento. Para acoplar un elemento secundario en otra direccin, debe establecer la propiedad LastChildFill en false y especificar adems una direccin de acoplamiento explcita para este ltimo elemento secundario. En el siguiente ejemplo se muestra el uso de un control DockPanel con varios controles contenidos. La propiedad DockPanel permite posicionar los objetos. <DockPanel LastChildFill="True"> <Border Height="25" Background="SkyBlue" BorderBrush="Black" BorderThickness="1" DockPanel.Dock="Top"> <TextBlock Foreground="Black">Dock = "Top"</TextBlock> </Border> <Border Height="25" Background="LemonChiffon" BorderBrush="Black" BorderThickness="1" DockPanel.Dock="Bottom"> <TextBlock Foreground="Black">Dock = "Bottom"</TextBlock> </Border> <Border Width="200" Background="PaleGreen" BorderBrush="Black" BorderThickness="1" DockPanel.Dock="Left"> <TextBlock Foreground="Black">Dock = "Left"</TextBlock> </Border> <Border Background="White" BorderBrush="Black" BorderThickness="1"> 35

<TextBlock Foreground="Black">This content will "Fill" the remaining space</TextBlock> </Border> </DockPanel>

Grid Define un rea de cuadrcula flexible que est compuesta de columnas y filas. Los elementos secundarios de Grid se dibujan en el orden en que aparecen en el cdigo. En consecuencia, se puede lograr un orden dispuesto en capas (tambin conocido como orden Z) cuando los elementos comparten las mismas coordenadas. Grid y Table comparten alguna funcionalidad comn, pero se puede aplicar cada uno de ellos en escenarios adecuados para hacer un mejor uso de sus caractersticas integradas. Grid agrega elementos basndose en un ndice de fila y columna; Table no lo hace. El elemento Grid permite la disposicin en capas del contenido si puede haber ms de un elemento dentro de una sola celda. Table no admite la disposicin en capas. Los elementos secundarios de un elemento Grid se pueden colocar de forma absoluta con respecto a la esquina superior izquierda de los lmites de su celda. Table no admite esta caracterstica. Grid tambin proporciona un comportamiento de cambio de tamao ms flexible que Table. Grid utiliza el objeto GridLength para definir las caractersticas de ajuste de tamao de RowDefinition o ColumnDefinition. En el siguiente ejemplo se muestra el uso del control Grid. La definicin inicial de filas y columnas y el uso de las propiedades Grid.Row y Grid.Column para asociar los controles contenidos a la celda correspondiente. <Grid VerticalAlignment="Top" HorizontalAlignment="Left" ShowGridLines="True" Width="250" Height="100" Canvas.Left="80" Canvas.Top="67" Background="LightYellow" > <Grid.ColumnDefinitions> <ColumnDefinition /> <ColumnDefinition /> <ColumnDefinition /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition /> <RowDefinition /> <RowDefinition /> <RowDefinition /> </Grid.RowDefinitions> <TextBlock FontSize="20" FontWeight="Bold" Grid.ColumnSpan="3" Grid.Row="0">Productos Comprados</TextBlock> <TextBlock FontSize="12" FontWeight="Bold" Grid.Row="1" Grid.Column="0">Enero</TextBlock> <TextBlock FontSize="12" FontWeight="Bold" Grid.Row="1" Grid.Column="1">Febrero</TextBlock> <TextBlock FontSize="12" FontWeight="Bold" Grid.Row="1" Grid.Column="2">Marzo</TextBlock> 36

<TextBlock Grid.Row="2" Grid.Column="0" TextAlignment="Right" >50,000</TextBlock> <TextBlock Grid.Row="2" Grid.Column="1" TextAlignment="Right">100,000</TextBlock> <TextBlock Grid.Row="2" Grid.Column="2" TextAlignment="Right">150,000</TextBlock> <TextBlock FontSize="16" FontWeight="Bold" Grid.ColumnSpan="3" Grid.Row="3">Total Units: 300,000</TextBlock> </Grid>

StackPanel Organiza los elementos secundarios en una nica lnea que se puede orientar horizontal o verticalmente. La propiedad Orientation permite organizar el contenido horizontal o verticalmente. En el siguiente ejemplo se muestra el uso del control StackPanel. La propiedad Orientation organiza los RadioButtons en forma vertical. <StackPanel Height="40" Width="115" Orientation="Vertical" > <RadioButton Name="rb1" Checked="rb_Checked" >Si</RadioButton> <RadioButton Name="rb2" Checked="rb_Checked" >No</RadioButton> </StackPanel>

GroupBox Representa un control que crea un contenedor que tiene un borde y un encabezado para el contenido de interfaz de usuario. Su propiedad de contenido es Content y su propiedad de encabezado es Header. En el siguiente ejemplo se muestra el uso del control GroupBox. La propiedad Header permite ponerle el ttulo. El uso de un StackPanel, otro de los controles contenedores, permite organizar el cuerpo del GroupBox. <GroupBox Width="100" Height="100" Background="Beige" > <GroupBox.Header> <Label>Employee Data</Label> </GroupBox.Header> <StackPanel> <RadioButton HorizontalAlignment="Left" Height="16" Name="Opcion1" Width="120">Opcin 1</RadioButton> <RadioButton HorizontalAlignment="Left" Height="16" Name="Opcion2" Width="120">Opcin 2</RadioButton> </StackPanel> </GroupBox> 37

Expander Representa el control que muestra un encabezado que tiene una ventana contraible que muestra el contenido. Su propiedad de contenido es Content y su propiedad de encabezado es Header. Si el contenido de la ventana expandida es demasiado grande para la ventana, puede ajustar el contenido de Expander en un control ScrollViewer para proporcionar el contenido desplazable. Expander no proporciona automticamente la funcin de desplazamiento. En el siguiente ejemplo se muestra el uso del control Expander. Las propiedades de este control permiten controlar la expansin y contraccin del cuerpo del mismo. <Expander Name="myExpander" HorizontalAlignment="Left" Header="Expandir" ExpandDirection="Down" IsExpanded="True" Width="100"> <TextBlock TextWrapping="Wrap"> Representa el control que muestra un encabezado que tiene una ventana contraible que muestra el contenido. </TextBlock> </Expander>

InkCanvas InkCanvas es un elemento que se puede utilizar para recibir y mostrar entradas de entrada manuscrita. Normalmente esta operacin se lleva a cabo mediante el uso de un lpiz o un mouse que interactan con un digitalizador para generar trazos de entrada manuscrita. Los trazos creados se representan como objetos Stroke y se pueden manipular mediante programacin o a travs de los datos proporcionados por el usuario. InkCanvas permite al usuario modificar o eliminar un objeto Stroke existente. <InkCanvas Name="ic" Background="LightSteelBlue" Canvas.Top="0" Canvas.Left="0" Height="200" Width="200" />

38

Menu Representa un control de men de Windows que le permite organizar jerrquicamente los elementos asociados a comandos y controladores de eventos. Presenta una lista de elementos que especifican comandos u opciones para una aplicacin. Normalmente, al hacer clic en un elemento de un men, se abre un submen o una aplicacin ejecuta un comando. MenuItem es el tipo ms comn de elemento de Menu. MenuItem puede contener elementos secundarios. En el siguiente ejemplo se muestra el uso del control Menu y la forma de crear los MenuItems. <Menu Name="menu1" Width="300" HorizontalAlignment="Left" VerticalAlignment="Top" > <MenuItem Header="_Archivo" > <MenuItem Header="A_brir" IsCheckable="true" /> <MenuItem Header="_Cerrar" IsCheckable="true" IsChecked="True" /> <MenuItem Header="_Guardar" > <MenuItem.Icon> <Image Source="setup.ico" Width="16" Height="16" /> </MenuItem.Icon> </MenuItem> <Separator /> <MenuItem Header="A_gregar" > <MenuItem Header="Proyecto" /> <MenuItem Header="Archivo" /> </MenuItem> </MenuItem> </Menu>

Frame Es un control de contenido que proporciona la capacidad para navegar y mostrar el contenido. Se puede hospedar dentro de otro contenido, como con otros controles y elementos. El 39

contenido puede ser cualquier tipo de objeto de .NET Framework y archivos HTML. En general, sin embargo, las pginas son la manera preferida de empaquetar contenido para la navegacin. A un contenido se puede navegar estableciendo la propiedad Source con el URI para el contenido deseado. Adems, a un contenido se puede navegar utilizando una de las sobrecargas del mtodo Navigate. <Frame Name="miFrame" Source="http://www.microsoft.com" />

WrapPanel Posiciona los elementos hijos en forma secuencial de izquierda a derecha, cortando el contenido de manera que quede sobre la lnea siguiente al llegar al borde del contenedor. El orden se mantiene de arriba hacia abajo o de derecha a izquierda dependiente del valor de la propiedad Orientation. <Border HorizontalAlignment="Left" VerticalAlignment="Top" BorderBrush="Black" BorderThickness="2"> <WrapPanel Background="LightBlue" Width="200" Height="100"> <Button Width="200">Button 1</Button> <Button>Button 2</Button> <Button>Button 3</Button> <Button>Button 4</Button> </WrapPanel> </Border>

40

3- Otros Controles
Label - AccessText Representa la etiqueta de texto de un control. Esta clase proporciona compatibilidad funcional y visual con las teclas de acceso. Se utiliza con frecuencia para permitir el acceso rpido desde el teclado a controles como TextBox. Para asociar un control Label a otro control, establezca la propiedad Target en el control que debe obtener el foco cuando el usuario presione la tecla de acceso. Para establecer la tecla de acceso, agregue un guin bajo antes del carcter que debe ser la tecla de acceso. Se accede con Alt + la letra seleccionada. En el siguiente ejemplo al presionar Alt+D, el foco se posiciona en TextBox2 <DockPanel Margin="0,10,3,3" Grid.Column="0" Grid.Row="5"> <TextBox Name="textBox2" Width="100" Height="20"/> <Label Target="{Binding ElementName=textBox2}"> <AccessText FontSize="12" FontWeight="Bold">E_ditar</AccessText> </Label> </DockPanel> <TextBox Name="textBox3" Width="100" Height="20" Canvas.Top="30" />

TextBox Representa un control que se puede utilizar para mostrar o editar texto sin formato. <TextBox Name="tbSelectSomeText" Width="100" > Algn Texto</TextBox>

TextBlock Proporciona un control ligero que permite mostrar pequeos fragmentos de contenido dinmico. TextBlock se ha diseado para que sea ligero y se ha preparado especficamente para integrar pequeos fragmentos de contenido dinmico en una interfaz de usuario (UI). TextBlock proporciona un rendimiento ptimo en la presentacin de lneas nicas y un rendimiento apropiado en la presentacin de hasta unas pocas lneas de contenido. <TextBlock Name="textBlock1" TextWrapping="Wrap" FontSize="14"> <Bold>TextBlock</Bold> esta diseado para ser <Italic>liviano</Italic> </TextBlock>

Button Su propiedad de contenido es Content. Su evento principal es Click. En el siguiente ejemplo se muestra un botn que contiene una imagen y un texto formado por controles contenidos. 41

<Button Name="btn5" Canvas.Left="64" Canvas.Top="17" Width="129" Height="33" Click="btnAceptar_Click" > <StackPanel Orientation="Horizontal" Width="Auto"> <Image Source="ms.jpg" Width="20" Height="20"></Image> <TextBlock Text="Aceptar" TextAlignment="Right" VerticalAlignment="Center" Width="69"></TextBlock> </StackPanel> </Button>

ListBox - ComboBox El ListBox permite mostrar una lista de tems desplegada. Las propiedades de contenido son las colecciones Items e ItemsSource. La propiedad SelectionMode permite establecer cuantos tems pueden ser seleccionados. La opciones son Single (1 solo tem), Multiple (varios tems) y Extended (se pueden seleccionar varios tems consecutivos usando la tecla Shift o no consecutivos usando la tecla Ctrl). El ComboBox permite ocultar y desplegar la lista de tems. Las propiedades IsEditable e IsReadOnly especifican cmo se comporta ComboBox cuando el usuario escribe una cadena para seleccionar un elemento o copia y pega un valor en el cuadro de texto. En el siguiente ejemplo vemos el uso de un ListBox sencillo. <ListBox Name="lb" Width="100" Height="55" SelectionChanged="PrintText" SelectionMode="Single"> <ListBoxItem>Item 1</ListBoxItem> <ListBoxItem>Item 2</ListBoxItem> <ListBoxItem>Item 3</ListBoxItem> </ListBox>

Estos controles permiten tambin el uso de listas con contengan CheckBox, imgenes, etc. como controles contenidos para cada tem. <ListBox Name="lb" Width="251" Height="119" SelectionMode="Single" SelectionChanged="lb_SelectionChanged"> <ListBoxItem Background="LightCoral" FontFamily="Verdana" FontSize="12" FontWeight="Bold"> <CheckBox Name="chk1"> <StackPanel Orientation="Horizontal"> <Image Source="ms.jpg" Height="30"></Image> <TextBlock Text="Item 1" Width="174"></TextBlock> </StackPanel> </CheckBox> </ListBoxItem> <ListBoxItem Background="Green" FontFamily="Verdana" FontSize="12" FontWeight="Bold"> <CheckBox Name="chk2"> 42

<StackPanel Orientation="Horizontal"> <Image Source="nextover.jpg" Height="30"></Image> <TextBlock Text="Item 2" Width="174"></TextBlock> </StackPanel> </CheckBox> </ListBoxItem> </ListBox>

<ComboBox Height="25" Width="150" HorizontalAlignment="Center" VerticalAlignment="Top" IsEditable="True"> <CheckBox Name="Item1">Buenos Aires</CheckBox> <CheckBox Name="Item2">Crdoba</CheckBox> <CheckBox Name="Item3">Mendoza</CheckBox> </ComboBox>

CheckBox Representa un control que un usuario puede activar y desactivar. Pueden tener tres estados: activado, desactivado e indeterminado. <CheckBox Name="Prueba" IsChecked="True">Prueba</CheckBox>

RadioButton Representa un botn que el usuario puede seleccionar, pero IsChecked de RadioButton se puede establecer haciendo clic en l, mediante programacin. Normalmente se lo utiliza como elemento RadioButton. La seleccin est determinada por el estado de su evento principal es Checked.

no borrar. La propiedad pero slo se puede borrar de un grupo de controles propiedad IsChecked. Su

<StackPanel Height="40" Canvas.Left="35" Canvas.Top="43" Width="115"> <RadioButton Name="rb1" Checked="rb_Checked">Si</RadioButton> <RadioButton Name="rb2" Checked="rb_Checked">No</RadioButton> <RadioButton Name="rb3" Checked="rb_Checked">No sabe/no contesta</RadioButton> </StackPanel>

43

Otros Controles ToolBar: Identifica una barra de herramientas, como el control que contiene un conjunto de botones de comando en una ventana de la aplicacin. Slider: Identifica un control deslizante. TreeView: Muestra datos jerrquicos, como una tabla de contenido, en una estructura de rbol. StatusBar: Identifica un control de barra de estado. ProgressBar: Identifica un control de barra de progreso, que indica visualmente el progreso de una operacin prolongada. PasswordBox: Representa un control diseado para escribir y administrar las contraseas. <StackPanel> <ToolBar Height="26" Name="toolBar1" Width="200" > <Button> <Image Source="setup.ico"/> </Button> <Button>Nuevo</Button> <Button>Abrir</Button> </ToolBar> <Slider Height="21" Name="slider1" Width="100" /> <TreeView Height="150"> <TreeViewItem Header="Archivo"> <TreeViewItem Header="Nuevo" /> <TreeViewItem Header="Abrir" /> <TreeViewItem Header="Cerrar" /> </TreeViewItem> <TreeViewItem Header="Editar"> <TreeViewItem Header="Cortar" /> <TreeViewItem Header="Copiar" /> <TreeViewItem Header="Pegar" /> </TreeViewItem> </TreeView> <StatusBar Height="23" Name="statusBar1" Width="120" > <TextBlock Height="15" Text="Procesando...." /> <ProgressBar Height="15" Name="progressBar1" Width="100" Value="20" /> </StatusBar> <PasswordBox Name="pwdBox" Width="100" MaxLength="64" PasswordChar="*" /> </StackPanel>

44

4- Informacin General de Controles


Propiedades Generales de los Controles BitmapEffect: Obtiene o establece efectos visuales. <Button.BitmapEffect> <BevelBitmapEffect /> </Button.BitmapEffect>

<Button.BitmapEffect> <DropShadowBitmapEffect /> </Button.BitmapEffect>

Focusable: Obtiene o establece un valor que indica si el foco se puede establecer en este elemento. Para exigir que un elemento del panel reciba el foco, establezca la propiedad Focusable en true. HorizontalAlignment: Obtiene o establece las caractersticas de alineacin horizontal que se aplican a este elemento cuando se crea dentro de un elemento primario, como un panel o control de elementos. IsEnabled: Obtiene o establece un valor que indica si este elemento est habilitado en la interfase de usuario. Margin: Permite establecer los mrgenes de un control con respecto a su contenedor. Se escribe en el siguiente formato (izquierda, arriba, derecha y abajo). Ejemplo: Margin="50,10,50,10" MaxHeight: Obtiene o establece la restriccin de alto mximo del elemento. MaxWidth: Obtiene o establece la restriccin de ancho mximo del elemento. MinHeigth: Obtiene o establece la restriccin de alto mnimo del elemento. MinWidth: Obtiene o establece la restriccin de ancho mnimo del elemento. Opacity: Permite generar objetos transparentes o semi transparentes. Los valores aceptados van del 0 al 1, siendo 0 totalmente transparente y 1 totalmente opaco. Padding: Obtiene o establece el relleno interior del control. El relleno se establece en el orden siguiente: izquierda, arriba, derecha y abajo. El valor predeterminado es un grosor de 0 en los cuatro lados. VerticalAlignment: Obtiene o establece las caractersticas de alineacin vertical que se aplican a este elemento cuando se crea dentro de un elemento primario, como un panel o control de elementos. Visibility: Obtiene o establece la visibilidad de la interfaz de usuario de este elemento.

Creacin dinmica de controles Todos los controles pueden ser tambin generados dinmicamente en tiempo de ejecucin. // Crea la ventana principal de la aplicacin mainWindow = new Window(); mainWindow.Title = "Grid Sample"; // Crea el control Grid Grid myGrid = new Grid(); myGrid.Width = 250; myGrid.Height = 100; 45

myGrid.HorizontalAlignment = HorizontalAlignment.Left; myGrid.VerticalAlignment = VerticalAlignment.Top; myGrid.ShowGridLines = true; // Define la columnas ColumnDefinition colDef1 = new ColumnDefinition(); ColumnDefinition colDef2 = new ColumnDefinition(); ColumnDefinition colDef3 = new ColumnDefinition(); myGrid.ColumnDefinitions.Add(colDef1); myGrid.ColumnDefinitions.Add(colDef2); myGrid.ColumnDefinitions.Add(colDef3); // Define las filas RowDefinition rowDef1 = new RowDefinition(); RowDefinition rowDef2 = new RowDefinition(); RowDefinition rowDef3 = new RowDefinition(); RowDefinition rowDef4 = new RowDefinition(); myGrid.RowDefinitions.Add(rowDef1); myGrid.RowDefinitions.Add(rowDef2); myGrid.RowDefinitions.Add(rowDef3); myGrid.RowDefinitions.Add(rowDef4); // Agrega el texto a la primera celda TextBlock txt1 = new TextBlock(); txt1.Text = "Productos Comprados"; txt1.FontSize = 20; txt1.FontWeight = FontWeights.Bold; Grid.SetColumnSpan(txt1, 3); Grid.SetRow(txt1, 0); ..................................

46

Mdulo 3

Personalizando la Apariencia de Aplicaciones WPF

47

1- Personalizar Apariencia
Composicin Un requisito habitual para personalizar la apariencia de un control es crear controles compuestos, o sea que incluyan ms de un control. La mayora de los controles WPF son contenedores de otros controles. Puede usar la composicin para incrustar los elementos XAML dentro de otros. En varios de los ejemplos mostrados en el captulo anterior usamos esta tcnica para la creacin de los controles. <Button Name="btn5" Canvas.Left="64" Canvas.Top="17" Width="129" Height="33" Click="btnAceptar_Click" > <StackPanel Orientation="Horizontal" Width="Auto"> <Image Source="ms.jpg" Width="20" Height="20"></Image> <TextBlock Text="Aceptar" TextAlignment="Right" VerticalAlignment="Center" Width="69"></TextBlock> </StackPanel> </Button>

Estilos Los estilos y plantillas permiten el mantenimiento y el uso compartido de la apariencia tanto dentro de una aplicacin como entre las diversas aplicaciones. Hacen referencia a un conjunto de caractersticas que permiten a los diseadores de aplicaciones, documentos o interfases de usuario crear aplicaciones visualmente atractivas y estandarizar la apariencia del producto. Otra caracterstica del modelo de estilos de WPF es la separacin de la presentacin y la lgica. Esto significa que los diseadores pueden trabajar en la apariencia de una aplicacin utilizando solamente XAML, al mismo tiempo que los desarrolladores trabajan en la lgica de programacin utilizando C# o Visual Basic. La clase Style permite generar los estilos en aplicaciones WPF. Puede establecer una clase Style en cualquier elemento que derive de FrameworkElement o FrameworkContentElement. Un estilo se suele declarar normalmente como un recurso de la seccin de Resources. Puesto que los estilos son recursos, siguen las mismas reglas de mbito que se aplican a todos los recursos; por tanto, cuando se declara un estilo, afecta a la parte donde se puede aplicar. Si, por ejemplo, se declara el estilo en el elemento raz del archivo XAML de definicin de la aplicacin, el estilo se puede usar en cualquier parte de la aplicacin. Si se crea una aplicacin de navegacin y se declara el estilo en uno de sus archivos XAML, el estilo slo se puede usar en ese archivo XAML. La declaracin de estilo est formada por un objeto Style que contiene una coleccin de uno o ms objetos Setter. Cada objeto Setter consta de una propiedad Property y una propiedad Value. La propiedad es el nombre de la propiedad del elemento al que se aplica el estilo. Una vez declarado el estilo como recurso, se puede hacer referencia a l como en el caso de cualquier otro recurso. Si hubiera muchos estilos con la misma propiedad Property es establece el valor del declarado en ltimo lugar. Si se establece la propiedad TargetType en un control sin asignar al estilo un atributo x:Key, el estilo se aplicar a todos los elementos de ese tipo. Esto significa que si se establece explcitamente el atributo x:Key en un valor, el objeto Style no se aplicar automticamente a todos los elementos de ese tipo. Si el estilo est en la seccin de recursos y no se establece la propiedad TargetType del estilo, se deber proporcionar un atributo x:Key. En el ejemplo siguiente se define un estilo que se aplicar a todas las instancias del elemento Button. Como se ve en el ejemplo los botones toman automticamente el estilo sin necesidad de asociarlo por cdigo. <Window.Resources> 48

<Style TargetType="{x:Type Button}"> <Setter Property="FontFamily" Value="Times New Roman" /> <Setter Property="FontSize" Value="30" /> <Setter Property="FontWeight" Value="Bold" /> <Setter Property="Background" Value="#FFCA5132" /> </Style> </Window.Resources> <Button Height="54" Name="button1" Width="134">Button</Button>

En el siguiente ejemplo se muestra una declaracin de estilo que afectar a la propiedad Background de una clase Control. La asignacin del estilo a un control se hace en forma explcita. <Window.Resources> <Style x:Key="Style1"> <Setter Property="Control.Background" Value="Yellow"/> </Style> </Window.Resources> <StackPanel> <Label Content="Label Amarillo" Style="{StaticResource Style1}" Width="100"/> <Button Name="button1" Style="{StaticResource Style1}" Height="20" Width="50">Button</Button> </StackPanel>

En el siguiente ejemplo el estilo se aplica al control StackPanel y sus controles contenidos y no a toda la ventana. <StackPanel> <StackPanel.Resources> <Style TargetType="Button"> <Setter Property="Background"> <Setter.Value> <LinearGradientBrush> <GradientStop Color="#DDDDDD" Offset="0" /> <GradientStop Color="#88FF88" Offset=".6" /> <GradientStop Color="#EEEEEE" Offset="1" /> </LinearGradientBrush> </Setter.Value> </Setter> </Style> </StackPanel.Resources> 49

<Button Height="50" Width="50"> <StackPanel> <TextBlock>Play</TextBlock> <Polygon Points="0,0 0,26 17,13" Fill="Black" /> </StackPanel> </Button> <Button Height="50" Width="50"> <StackPanel> <TextBlock>Play</TextBlock> <Polygon Points="0,0 0,26 17,13" Fill="Black" /> </StackPanel> </Button> </StackPanel>

Nota: Muchos controles de WPF constan de una combinacin de otros controles de WPF, por lo que la creacin de un estilo que se aplique a todos los controles de un tipo puede tener un gran impacto. Por ejemplo, si se crea un estilo cuyo destino son los controles TextBlock de un control Canvas, el estilo se aplica a todos los controles TextBlock del lienzo, aunque TextBlock forme parte de otro control, como ListBox.

Plantillas Los estilos estn limitados a la configuracin de las propiedades predeterminadas en elementos XAML. Para una libertad completa de una apariencia del control, necesita usar plantillas. Para ello, debe crear un estilo y especificar la propiedad de plantilla. El valor de la propiedad de plantilla pasa a ser un elemento ControlTemplate que especifica cmo redactar el control. La mayora de controles tienen una apariencia y un comportamiento. Considere un botn: la apariencia es el rea elevada que se puede presionar y el comportamiento es el evento Click que se provoca en respuesta a un clic. En ocasiones, puede haber un control que proporcione el comportamiento necesario, pero no la apariencia necesaria. Hasta ahora, hemos mostrado que puede utilizar establecedores de estilo para establecer valores de propiedad que afecten a la apariencia del control. Sin embargo, para cambiar la estructura de un control o establecer valores de propiedad en los componentes de un control, debe utilizar un objeto ControlTemplate. En WPF, el objeto ControlTemplate de un control define su apariencia. Puede cambiar la estructura y la apariencia de un control definiendo un nuevo objeto ControlTemplate para el control. En muchos casos, esto ofrece suficiente flexibilidad como para no tener que escribir controles personalizados. En el siguiente ejemplo se ha especificado un botn en forma de crculo con el icono de reproduccin en el centro, colocando el icono de reproduccin sobre un elemento elipse. El nuevo botn de plantilla aparece junto a un botn normal. 50

<StackPanel> <StackPanel.Resources> <Style TargetType="{x:Type Button}" x:Key="PlayButton" > <Setter Property="Template"> <Setter.Value> <ControlTemplate> <Grid> <Ellipse Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" Stroke="DarkGray" VerticalAlignment="Top" HorizontalAlignment="Left" Fill="LightGray" /> <Polygon Points="18,12 18,38 35,25" Fill="Black" /> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style> </StackPanel.Resources> <Button Height="50" Width="100">Botn Normal</Button> <Button Height="50" Width="50" Style="{StaticResource PlayButton}" /> </StackPanel>

Otro ejemplo de cmo aplicar plantillas. Tenga en cuenta que la plantilla se aplica siempre a travs de un estilo. Este ejemplo usa una plantilla que a travs de un control Border redondea la forma de los botones. <Window.Resources> <ControlTemplate x:Key="PlantBotonAzul" TargetType="{x:Type Button}"> <Border BorderBrush="Navy" BorderThickness="1" CornerRadius="5" Background="CornflowerBlue"> <Grid> <Grid.RowDefinitions> <RowDefinition /> </Grid.RowDefinitions> <ContentPresenter Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center" /> </Grid> </Border> </ControlTemplate> <Style x:Key="EstiloBotonAzul" TargetType="{x:Type Button}"> <Setter Property="Template" Value="{StaticResource PlantBotonAzul}" /> </Style> </Window.Resources> <Button Height="40" Name="button1" Width="120" Content="Aceptar" Style="{StaticResource EstiloBotonAzul}" />

51

Desencadenadores (Triggers) La clase Trigger representa un desencadenador que aplica valores de propiedad o realiza acciones si se cumplen determinadas condiciones. WPF define propiedades que se corresponden con acciones del usuario final, como la propiedad IsMouseOver cuyo valor se establece en true cuando el usuario desplaza el puntero sobre un objeto, o bien, la correspondiente propiedad IsMouseOver de un objeto. La representacin de las acciones del usuario final en los valores de propiedad junto con el elemento Trigger permite a los estilos de WPF cambiar en el marcado los valores de las propiedades segn esas acciones del usuario final. Las propiedades cambiadas por los desencadenadores se restablecen automticamente en su valor anterior si ya no se cumple la condicin de activacin. Los desencadenadores se optimizan para los estados transitorios de los que se espera que cambien y vuelvan a su estado original, como IsPressed en el control Button e IsSelected en el control ListBoxItem. La propiedad Property de inters debe ser una propiedad de dependencia. Observe que debe especificar las propiedades Property y Value en un objeto Trigger para que el desencadenador tenga sentido. La propiedad Setters de un objeto Trigger slo puede estar formada por objetos Setter. En el siguiente ejemplo se muestra el uso de desencadenadores de manera que cada vez que se hace clic sobre un botn este cambia el tamao de la letra de su contenido a 14 y cada vez que se pasa el Mouse por encima del mismo el color del fondo se vuelve rojo. <Window.Resources> <Style x:Key="TrCambioColor" TargetType="{x:Type Button}"> <Style.Triggers> <Trigger Property="IsPressed" Value="true"> <Setter Property = "FontSize" Value="14"/> </Trigger> <Trigger Property="IsMouseOver" Value="true"> <Setter Property = "Background" Value="red"/> </Trigger> </Style.Triggers> </Style> </Window.Resources> <StackPanel > <Button Height="23" Name="button1" Width="75" Style="{StaticResource TrCambioColor}">Button</Button> </StackPanel>

Otro tipo de desencadenador es EventTrigger, que inicia un conjunto de acciones en funcin de la aparicin de un evento. Los objetos EventTrigger inician un conjunto de propiedades Actions cuando se produce un evento enrutado especificado. Por ejemplo, quiz desee usar EventTrigger para iniciar un conjunto de animaciones cuando el puntero del mouse est sobre 52

cierto control de la interfaz de usuario (UI). A diferencia de Trigger, EventTrigger no tiene ningn concepto de finalizacin de estado, por lo que no se deshar la accin una vez que la condicin que provoc el evento deje de ser verdadera. Tenga en cuenta que al usar EventTrigger, debe elegir eventos que no interfieran con el comportamiento inherente del control. Los controles como Button o TextBox realizan acciones concretas en los eventos de usuario como clics del mouse y eventos de teclado. Por ejemplo, si est creando un botn e intenta establecer el evento MouseDown como la propiedad RoutedEvent de EventTrigger, EventTrigger nunca se aplica porque el botn administra primero el evento. En su lugar, puede usar el evento PreviewMouseDown o un evento diferente. En el siguiente ejemplo, los objetos EventTrigger especifican que, cuando el puntero del mouse entre en el elemento Button, la propiedad Height se establezca en 90 durante un perodo de 0.2 segundos. Cuando el mouse sale del elemento, la propiedad se establece de nuevo en el valor original durante un perodo de 1 segundo. Note que se escriben ambos eventos de manera que la accin se detenga al cambiar el estado. <Window.Resources> <Style x:Key="TrCambioColor" TargetType="{x:Type Button}"> <Style.Triggers> <EventTrigger RoutedEvent="Mouse.MouseEnter"> <EventTrigger.Actions> <BeginStoryboard> <Storyboard> <DoubleAnimation Duration="0:0:0.2" Storyboard.TargetProperty="Height" To="90" /> </Storyboard> </BeginStoryboard> </EventTrigger.Actions> </EventTrigger> <EventTrigger RoutedEvent="Mouse.MouseLeave"> <EventTrigger.Actions> <BeginStoryboard> <Storyboard> <DoubleAnimation Duration="0:0:1" Storyboard.TargetProperty="Height" /> </Storyboard> </BeginStoryboard> </EventTrigger.Actions> </EventTrigger> </Style.Triggers> </Style> </Window.Resources> <StackPanel > <Button Height="23" Name="button1" Width="75" Style="{StaticResource TrCambioColor}">Button</Button> </StackPanel>

53

Adems de Trigger y EventTrigger, hay otros tipos de desencadenadores. MultiTrigger permite establecer valores de propiedad en funcin de varias condiciones. DataTrigger y MultiDataTrigger se utilizan cuando la propiedad de la condicin est enlazada a datos.

2- Crear Controles de Usuario


Controles Es imposible suministrar todos los controles que se podran necesitar. Por este motivo existe la creacin de controles. En Windows Presentation Foundation, la composicin, el estilo y las plantillas habilitan la personalizacin de los controles existentes hasta un nivel sin precedentes en tecnologas anteriores, pero la creacin de controles permite armar controles una nica vez y re usarlos en distintos formularios o proyectos. El primer paso que debe dar antes de escribir su propio control es decidir qu mtodo va a usar para crearlo. Existen dos maneras principales de crear controles en Windows Presentation Foundation: los controles de usuario y los controles personalizados. Ambos enfoques ofrecen ventajas. Controles de usuario: Es un fragmento de una ventana o pgina. Permite incluir varios controles y su funcionalidad como una forma de encapsulamiento visual. Se los llama tambin controles compuestos. Controles personalizados: Generalmente heredan de un solo control y nos permiten sumar funcionalidad o apariencia al mismo. Su propsito es mejorar los controles existentes.

Controles de Usuario Lo primero que debe hacer al crear un control de usuario es agregar un elemento nuevo a su proyecto. Si hace clic al proyecto con el botn secundario y luego a Agregar, no elija la opcin de Control de Usuario del men contextual. Lamentablemente, esta funcin intentar crear un control de usuario nuevo de Windows Forms. En su lugar, escoja la opcin Agregar nuevo elemento. En el dilogo Agregar nuevo elemento, escoja el elemento Control de Usuario (WPF).

54

Al crear el control de usuario nuevo se crea un archivo XAML y un archivo de cdigo de seguridad. El archivo XAML es semejante al archivo principal, creado con proyectos nuevos de Windows Presentation Foundation; la diferencia es que el elemento raz del archivo XAML nuevo es un elemento UserControl. Dentro del elemento UserControl debe crear el contenido que configurar su control. En el siguiente ejemplo se crea un UserControl para armar un botn redondo con el smbolo de play. <UserControl x:Class="WpfCSharp.UserControlWPF" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Height="55" Width="55"> <Grid> <Ellipse Width="50" Height="50" Stroke="DarkGray" VerticalAlignment="Top" HorizontalAlignment="Left" Name="BotonNegro" Fill="LightGray" /> <Polygon Name="IconoPlay" Points="18,12 18,38 35,25" Fill="Black" /> </Grid> </UserControl> A continuacin se muestra el cdigo para usar el control en una ventana. Antes de poder usar un control de usuario en una ventana debe referenciar la ventana al espacio de nombres y darle un alias a dicha referencia. Eso se hace agregando la lnea xmlns:UC="clr-namespace:WpfCSharp" donde UC es el nombre que se va a dar al namespace del control. Si el control estuviera en otro ensamblado la lnea a ingresar es xmlns:cust=clr-namespace:CustomWPF;assembly=CustomWPF 55

<Window x:Class="WpfCSharp.Window2" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:UC="clr-namespace:WpfCSharp" Title="Window2" Height="300" Width="500" > <StackPanel> <TextBlock>Prueba de usercontrol</TextBlock> <UC:UserControlWPF HorizontalAlignment="left" /> </StackPanel> </Window>

Personalizando Controles de Usuario Cuando se crean controles muchas veces es necesario generar cdigo no solo para poder interactuar con ellos, sino para encapsular funcionalidad. Al crear los controles descubrir que es necesario implementar las propiedades, mtodos y/o eventos para administrar tanto la apariencia del control como su comportamiento en el tiempo de ejecucin. Por ejemplo, sera importante en el control creado en el ejemplo anterior obtener y establecer el color del icono. Para ello, se puede crear una propiedad como se muestra a continuacin. Brush _ColorIcono = Brushes.Black; public Brush ColorIcono { get { return _ColorIcono; } set { _ColorIcono = value; IconoPlay.Fill = _ColorIcono; } } Y en la ventana que usa a este control se asigna el valor de la propiedad como cualquiera de las otras propiedades del control. <StackPanel> <TextBlock>Prueba de usercontrol</TextBlock> <UC:UserControlWPF HorizontalAlignment="left" ColorIcono="Red" /> </StackPanel>

56

Tambin podramos crear un Control de Usuario WPF y cambiar las referencias a la clase UserControl por el control con el cual se desea trabajar, de manera de personalizar solamente un control. <Button x:Class="Pruebas.controlPrueba" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Height="23" Width="100"> </Button> public partial class controlPrueba : Button { public controlPrueba() { InitializeComponent(); } }

Controles Personalizados Si deseamos agregar a la aplicacin un control personalizado lo hacemos desde Agregar Elementos, Control Personalizado.

Una vez creado veremos la diferencia con respecto a los controles de usuario. Estos controles no tienen cdigo XAML, por lo tanto necesitamos crear los controles que vayamos a utilizar mediante cdigo subyacente lo cual genera un desarrollo mucho ms complejo.

57

Mdulo 4

Enlace a Datos

58

1- Enlazar Datos
Enlace a Datos El enlazado de datos es el proceso que permite establecer una conexin entre la interfase de usuario y la lgica de negocios. Si el enlace es correcto y los datos proveen notificaciones correctamente, al cambiar los datos los elementos enlazados a ellos reflejan el cambio automticamente y a su vez tambin debera funcionar en sentido inverso, o sea si modificamos el valor sobre los elementos, el dato asociado tambin se modifica. WPF proporciona una forma eficaz de enlace de datos. Con WPF, puede realizar la manipulacin de datos mediante cdigo Microsoft .NET Framework, XAML o una combinacin de ambos. Puede realizar el enlace a controles, propiedades pblicas, XML u objetos, convirtiendo las operaciones de enlace de datos en tareas rpidas, flexibles y realmente fciles. Para usar el enlace de datos de WPF, debe disponer siempre de un destino y un origen. El destino del enlace puede ser cualquier elemento o propiedad accesible que se derive de DependencyProperty, un ejemplo es la propiedad Text del control TextBox. El origen del enlace puede ser cualquier propiedad Public, incluidas propiedades de otros controles, objetos de common language runtime (CLR), elementos XAML, DataSets de ADO.NET, fragmentos XML, etc.

Clase Binding Define un enlace que conecta las propiedades de destinos de enlace y de orgenes de datos. Cada enlace debe especificar el elemento de destino, la propiedad de destino y el origen de datos. Las propiedades de uso ms comn de esta clase son: Source: Referencia a la fuente de datos. ElementName: El nombre del control al cual enlazamos una propiedad, se usa como alternativa de Source cuando el enlace es entre controles. Path: Indica la propiedad del elemento al cual enlazaremos el dato Converter: Instancia de una clase que implementa la interfase IValueConverter, que intercepta los movimientos de datos entre el origen y el destino de los datos o viceversa y permite la conversin de datos, el formateo de los mismo, etc. Son muy convenientes y se utilizan con frecuencia Al crear un enlace se usar la propiedad ElementName cuando el enlace se genera contra otro elemento WPF. Se usar la propiedad Source cuando el objeto a enlazar no es un elemento WPF, por ejemplo cuando es un recurso. No es necesario especificar ninguno de esas dos propiedades cuando el enlace se hace mediando el uso del objeto DataContext. Modos de Enlazar Propiedad Mode La etiqueta Binding permite tambin el atributo Mode. El atributo Mode define el modo de enlace que determinar el flujo de datos entre el origen y el destino. 59

OneWay: los datos fluyen desde el origen hasta el destino cada vez que se realiza un cambio en el origen. Es el modo predeterminado OneTime: Enva datos desde el origen al destino; sin embargo, hace esto slo cuando se inicia la aplicacin o cuando cambia el DataContext y, como resultado, no espera notificaciones de cambio en el origen. OneWayToSource: Enva datos desde el destino al origen. TwoWay: Enva los datos del origen al destino y si hay cambios en el valor de la propiedad de destino, stos volvern a enviarse al origen. La seleccin del modo de enlace apropiado es muy importante. Con frecuencia se emplea OneWay cuando se desea mostrar los datos a un usuario. Se usa TwoWay cuando se desea que el usuario pueda cambiar los datos en el control y que ese cambio se refleje en el origen de datos (por ejemplo un DataSet, objeto, XML u otro control de enlace). Se usa OneWayToSource cuando se desea permitir a un usuario cambiar el origen de datos sin que el origen de datos tenga que volver a enlazar sus datos al destino y se usa OneTime cuando se desea cargar datos de solo lectura al cargar la pantalla y que estos permanezcan sin cambios aunque se efecten cambios en el origen de datos.

DataContext="{Binding ElementName=Customer,Path=Items,Mode=OneWay}"

Momento del Enlace Por defecto el momento del enlace esta predefinido en cada control. Por ejemplo en el caso del ListBox el enlace se hace al momento de seleccionar un elemento, en cambio en el caso de un TextBox el enlace ocurre al perder el foco. Para cambiar el evento que provoca la devolucin de los datos al origen, puede especificar un valor para el atributo UpdateSourceTrigger, que es la propiedad de enlace que define cundo debe actualizarse el origen. Hay cuatro valores que pueden configurarse para UpdateSourceTrigger: Default: se actualizar en el evento asociado por defecto al control Explicit: el origen no se actualizar a menos que se llame desde el cdigo al mtodo UpdateSource de la clase BindingExpression. LostFocus: indica que el origen se actualizar cuando el control del destino pierda el foco. PropertyChanged: indica que el destino actualizar el origen cada vez que cambie la propiedad enlazada del control del destino. Esta configuracin es til si desea establecer el momento del enlace de forma personalizada. En este ejemplo a medida que escribe en el TextBox se va escribiendo en el TextBlock, ya que el enlazado est sobre la propiedad Text y el momento establecido con la opcin PropertyChanged es la modificacin de esa propiedad: <StackPanel> <StackPanel.Resources> <TextBlock x:Key=" miFuente "></TextBlock> </StackPanel.Resources> 60

<Label>Ingrese el nombre:</Label> <TextBox> <TextBox.Text> <Binding Source="{StaticResource miFuente }" Path="Name" UpdateSourceTrigger="PropertyChanged"/> </TextBox.Text> </TextBox> <Label>El nombre ingresado es:</Label> <TextBlock Text="{Binding Source={StaticResource miFuente }, Path=Name}"/> </StackPanel> Si modifica el valor de UpdateSourceTrigger a Default, el TextBlock se actualizar al perder el foco del TextBox, ya que ese es el evento predeterminado para ese control. En cambio si establece esta propiedad en Explicit deber invocar al mtodo UpdateSource de la clase BindingExpression. En el siguiente ejemplo se agreg un botn que en su evento Click que invoca a dicho mtodo. De esta manera para actualizar el dato deber presionar el botn que crea una instancia de la clase BindingExpression e invoca al mtodo UpdateSource. <StackPanel> <StackPanel.Resources> <TextBlock x:Key="miFuente"></TextBlock> </StackPanel.Resources> <Label>Ingrese el Nombre:</Label> <TextBox Name="txtNombre"> <TextBox.Text> <Binding Source="{StaticResource miFuente}" Path="Name" UpdateSourceTrigger="Explicit" /> </TextBox.Text> </TextBox> <Button Height="23" Width="70" Content="Actualizar" Click="Button_Click"></Button> <Label>El nombre ingresado:</Label> <TextBlock Text="{Binding Source={StaticResource miFuente}, Path=Name}"/> </StackPanel> En la ventana de cdigo: private void Button_Click(object sender, RoutedEventArgs e) { BindingExpression be = txtNombre.GetBindingExpression(TextBox.TextProperty); be.UpdateSource(); }

Propiedad Asociadas al Enlace de Datos BindsDirectlyToSource: Esta propiedad establece un valor que indica si se va a evaluar la propiedad Path con respecto al elemento de datos o al objeto ObjectDataProvider. El valor por defecto de esta propiedad es false. Cuando es false evala la ruta de acceso con respecto al elemento de datos propiamente dicho; de lo contrario, cuando es verdadero, evaluar la ruta de acceso respecto al objeto ObjectDataProvider. En el ejemplo anterior debe estar en true, ya que la propiedad Path tiene el valor de una propiedad de ObjectDataProvider(MethodParameters) y no del elemento de datos. 61

DisplayMemberPath: Indica el nombre de la propiedad del objeto de origen que ser mostrada en el elemento enlazado. ItemsSource: Representa la coleccin que contiene los datos. Se usa cuando se enlaza a colecciones. IsSynchronizedWithCurrentItem: Indica si la seleccin debe mantener la propiedad SelectedItem sincronizada con el elemento actual en la propiedad Items. Puede establecer el valor de la propiedad IsSynchronizedWithCurrentItem en true para asegurarse de que el elemento seleccionado siempre se corresponde con la propiedad CurrentItem de ItemCollection. Se usa mucho en relaciones Cabecera-Detalle. Por ejemplo, suponga que existen dos controles ListBox con su propiedad ItemsSource establecida en el mismo origen. Establezca la propiedad IsSynchronizedWithCurrentItem en true en ambos cuadros de lista para asegurarse de que el elemento seleccionado en cada ListBox sea el mismo.

Enlace entre Controles Es posible enlazar dos controles de manera de sincronizar los valores entre ellos. En el siguiente ejemplo se enlaza la propiedad Text de un TextBlock a un elemento seleccionado de un control ListBox. <StackPanel> <ListBox x:Name="lbProvincias" Width="248" Height="80"> <ListBoxItem Content="Buenos Aires"/> <ListBoxItem Content="Crdoba"/> <ListBoxItem Content="Mendoza"/> <ListBoxItem Content="Salta"/> <ListBoxItem Content="Neuquen"/> </ListBox> <TextBlock Width="248" Height="24" Text="Provincia elegida:" /> <TextBlock Width="248" Height="24"> <TextBlock.Text> <Binding ElementName="lbProvincias" Path="SelectedItem.Content"/> </TextBlock.Text> </TextBlock> </StackPanel>

La propiedad Text del TextBlock declara un enlace al elemento seleccionado del ListBox con la etiqueta <Binding>. El atributo ElementName de la etiqueta Binding indica el nombre del control al cual est enlazada la propiedad Text de TextBlock. El atributo Path indica la propiedad del elemento (en este caso ListBox) a la cual realizaremos el enlace. El resultado de este cdigo es que cuando se selecciona una provincia del ListBox, el nombre de esa provincia se muestra en TextBlock. 62

El cdigo anterior tambin puede escribirse de manera abreviada: <TextBlock Width="248" Height="24" Text="{Binding ElementName=lbProvincias, Path=SelectedItem.Content}" />

XmlDataProvider El objeto XmlDataProvider puede usarse como origen de datos. Este objeto puede enlazar a un documento o fragmento XML que se encuentre incrustado en la etiqueta o en un archivo al que se hace referencia en una ubicacin externa. Se debe dar a XmlDataProvider un valor x:Key de manera que se pueda hacer referencia a l a travs de los destinos de enlace de datos. Tenga en cuenta el atributo XPath. Este atributo define el nivel del contenido XML que se usar como el origen de datos. Esto es muy til cuando se enlaza a una estructura XML grande que puede incluirse en un archivo o base de datos y los datos a los que desea realizar el enlace no constituyen el elemento raz. El contenido XML incrustado debe colocarse en una etiqueta <x:XData>.

En este ejemplo los datos XML estn incrustados dentro del XMLDataProvider <StackPanel> <StackPanel.Resources> <XmlDataProvider x:Key="Colores" XPath="/colores"> <x:XData> <colores> <color name="Azul"/> <color name="Verde"/> <color name="Amarillo"/> <color name="Blanco"/> <color name="Negro"/> </colores> </x:XData> </XmlDataProvider> </StackPanel.Resources> <ListBox x:Name="lbColor" Width="248" Height="56" ItemsSource="{Binding Source={StaticResource Colores}, XPath=color/@name}"> </ListBox> </StackPanel> Se puede crear un archivo XML y luego referenciar dicho archivo usando XMLDataProvider. El ejemplo siguiente enlaza a un archivo llamado Colores.xml. <StackPanel.Resources> <XmlDataProvider x:Key="Colores" Source="Colores.xml" XPath="/colores"/> </StackPanel.Resources> Archivo Colores.xml <?xml version="1.0" encoding="utf-8" ?> <colores > <color name="Azul"/> <color name="Verde"/> <color name="Amarillo"/> 63

<color name="Blanco"/> <color name="Negro"/> </colores>

ObjectDataProvider Si se desea realizar un enlace a un objeto o a una lista de objetos, se puede utilizar el objeto ObjectDataProvider como un recurso. La propiedad ObjectType del ObjectDataProvider designa el objeto que proporcionar el origen de enlace de datos mientras que la propiedad MethodName indica el mtodo que ser invocado para obtener los datos. Existe otra serie de propiedades disponibles en ObjectDataProvider. La propiedad ConstructionParameters le permite pasar los parmetros al constructor de la clase que se invoca. Puede especificar tambin los parmetros mediante la propiedad MethodParameters y usar la propiedad ObjectInstance para especificar una instancia existente de un objeto como el origen. Si desea que los datos se recuperen de manera asincrnica, puede configurar la propiedad IsAsynchronous de ObjectDataProvider en true. A continuacin el usuario podr interactuar con la pantalla mientras espera que los datos rellenen el control de destino que est enlazado con el origen de ObjectDataProvider. Al agregar un ObjectDataProvider, es necesario calificar el espacio de nombres de la clase de origen de datos. En este caso, tengo que agregar un atributo xmlns a la etiqueta <Window> para que se califique el acceso directo y ste indique el espacio de nombres apropiado. En el siguiente ejemplo se crea una clase llamada Pases la cual contiene un mtodo llamado TraerPaises, el cual devuelve todos los pases de una tabla de la base de datos AdventureWorks de SQL Server. public class Paises { public DataTable TraerPaises() { using (DataTable dt = new DataTable()) { using (SqlConnection cn = new SqlConnection(WpfCSharp.Properties.Settings.Default.AdvWorks)) { using (SqlDataAdapter da = new SqlDataAdapter("Select * from Person.CountryRegion", cn)) { da.Fill(dt); } } return dt; } } }

64

Una vez generada la clase podemos generar la referencia al mtodo usando el control ObjectDataProvider y asociarla a un control enlazable. Para poder llamar a la clase Paises deber generar la referencia con la lnea xmlns:svc="clr-namespace:WpfCSharp al igual que en el uso de controles. <Window x:Class="WpfCSharp.Window2" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Window2" Height="300" Width="500" xmlns:svc="clr-namespace:WpfCSharp"> <StackPanel> <StackPanel.Resources> <ObjectDataProvider x:Key="misPaises" ObjectType="{x:Type svc:Paises}" MethodName="TraerPaises"/> </StackPanel.Resources> <ListBox x:Name="lbPersons" Height="250" Width="200" ItemsSource="{Binding Source={StaticResource misPaises}}" DisplayMemberPath="Name" /> </StackPanel> </Window>

MethodParameters Permite armar la lista de parmetros para pasarlos en la llamada al mtodo definido en la propiedad MethodName. El ejemplo siguiente muestra una clase Provincias que contiene un mtodo TraerProvincias que recibe un parmetro de tipo carcter que permite devolver solo las provincias asociadas al cdigo del pas recibido. public class Provincias { public DataTable TraerProvincias(string Cod) { using (DataTable dt = new DataTable()) { using (SqlConnection cn = new SqlConnection(WpfCSharp.Properties.Settings.Default.AdvWorks)) 65

{ using (SqlDataAdapter da = new SqlDataAdapter("Select * From Person.stateProvince Where CountryRegionCode=@Cod", cn)) { da.SelectCommand.Parameters.Add(new SqlParameter("@Cod", SqlDbType.Char, 3)); da.SelectCommand.Parameters["@Cod"].Value = Cod; da.Fill(dt); } } return dt; } } }

Usando ObjectDataProvider generamos la referencia a este mtodo y con MethodParametes definimos su parmetro. Luego asociamos ese parmetro a un TextBox de manera de poder seleccionar distintos valores y mostramos la lista de provincias en un ListBox. <Window x:Class="WpfCSharp.Window2" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Window2" Height="300" Width="500" xmlns:svc="clr-namespace:WpfCSharp" xmlns:system="clr-namespace:System;assembly=mscorlib" > <StackPanel> <StackPanel.Resources> <ObjectDataProvider x:Key="ProvxPais" ObjectType="{x:Type svc:Provincias}" MethodName="TraerProvincias"> <ObjectDataProvider.MethodParameters> <system:String>US</system:String> </ObjectDataProvider.MethodParameters> </ObjectDataProvider> </StackPanel.Resources> <TextBox Name="txtPais" Width="200"> <TextBox.Text> <Binding Source="{StaticResource ProvxPais}" Path="MethodParameters[0]" BindsDirectlyToSource="true" UpdateSourceTrigger="PropertyChanged"/> </TextBox.Text> </TextBox> <ListBox x:Name="lbPersons" Height="250" Width="200" ItemsSource="{Binding Source={StaticResource ProvxPais}}" DisplayMemberPath="Name" /> </StackPanel> </Window>

66

DataTemplate Se usa para generar una visualizacin de los datos personalizada. DataTemplate es el objeto que permite armar la plantilla de datos. En el siguiente ejemplo usa DataTemplate para modificar la apariencia de la lista de manera que el nombre del pas se vea en negrita. <Window x:Class="WpfCSharp.Window2" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Window2" Height="300" Width="500" xmlns:svc="clr-namespace:WpfCSharp"> <StackPanel> <StackPanel.Resources> <ObjectDataProvider x:Key="misPaises" ObjectType="{x:Type svc:Paises}" MethodName="TraerPaises"/> <DataTemplate x:Key="LayoutPais" > <StackPanel Orientation="Horizontal" > <TextBlock Text="{Binding Path=CountryRegionCode}" /> <TextBlock Text=" - " /> <TextBlock Text="{Binding Path=Name}" FontWeight="Bold" /> </StackPanel> </DataTemplate> </StackPanel.Resources> <ListBox x:Name="lbPersons" Height="250" Width="200" ItemsSource="{Binding Source={StaticResource misPaises}}" ItemTemplate="{DynamicResource LayoutPais}" /> </StackPanel> </Window>

67

DataContext Todos los controles que derivan de FrameworkElement tienen la propiedad DataContext. Esta propiedad permite relacionarse con los datos. La propiedad DataContext es heredada por los elementos hijos del elemento al cual est asociada, por lo cual se recomienda asociarla a los elementos contenedores. Es muy til para construir formularios en donde varias propiedades se asocian a datos de la misma fuente de datos. En el siguiente ejemplo enlaza el origen de datos al objeto Grid, de esta manera que todos los controles contenidos especifican solo el nombre del campo ya que el enlace principal est asociado a su contenedor. <Window x:Class="WpfCSharp.Window2" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Window2" Height="300" Width="500"> <Window.Resources> <ObjectDataProvider x:Key="misPaises" ObjectType="{x:Type svc:Paises}" MethodName="TraerPaises"/> </Window.Resources> <Grid DataContext="{StaticResource misPaises}"> <Grid.ColumnDefinitions> <ColumnDefinition /> <ColumnDefinition /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition /> <RowDefinition /> <RowDefinition /> <RowDefinition /> </Grid.RowDefinitions> <TextBlock Grid.Column="0" Grid.Row="0" Height="21" Name="txbCodigo" Text="Cdigo:" /> <TextBlock Grid.Column="0" Grid.Row="1" Height="21" Name="txbNombre" Text="Nombre:" /> <TextBlock Grid.Column="0" Grid.Row="2" Height="21" Name="txbFecha" Text="Fecha:" /> <TextBox Grid.Column="1" Grid.Row="0" Height="23" Name="txtCodigo" Text="{Binding CountryRegionCode}"/> 68

<TextBox Grid.Column="1" Grid.Row="1" Height="23" Name="txtNombre" Text="{Binding Name}"/> <TextBox Grid.Column="1" Grid.Row="2" Height="23" Name="txtFecha" Text="{Binding ModifiedDate}"/> </Grid> </Window>

Controles ListView - Gridview WPF no tiene un control GridView pero este puede generarse usando un control ListView. ListView contiene una propiedad View que provee un objeto GridView. La propiedad Columns de un GridView contiene elementos del tipo GridViewColumn. La propiedad AllowsColumnReorder permite establecer si la columnas soportan ordenado o no. En el siguiente ejemplo usando la misma clase Pases declarada en el ejemplo anterior generamos un ListView y organizamos las columnas del mismo usando el objeto GridView. <Window.Resources> <ObjectDataProvider x:Key="misPaises" ObjectType="{x:Type svc:Paises}" MethodName="TraerPaises"/> </Window.Resources> <ListView Height="150" Width="280" ItemsSource="{Binding Source={StaticResource misPaises}}" > <ListView.View> <GridView> <GridView.Columns> <GridViewColumn Width="50" Header="Cdigo" DisplayMemberBinding="{Binding Path=CountryRegionCode}"/> <GridViewColumn Width="200" Header="Nombre" DisplayMemberBinding="{Binding Path=Name}"/> </GridView.Columns> </GridView> </ListView.View> </ListView>

69

2- Notificaciones de Cambio de Propiedad


Interfase INotifyPropertyChanged Permite notificar a un cliente que el valor de una propiedad cambi. Se usa generalmente en clientes enlazados para notificarlos que una propiedad fue modificada. Para controlar estas notificaciones entre clientes y fuentes de datos enlazados se podra hacer de dos maneras: Implementar una clase con la interfase INotifyPropertyChanged Generar eventos de cambios para cada propiedad La primera opcin es la recomendada. Supongamos el siguiente ejemplo. Tenemos una clase Persona con dos propiedades Nombre y Edad. public class Persona { private string _Nombre; public string Nombre { get { return _ Nombre; } set { _ Nombre =value;} } int _Edad; public int Edad { get { return _Edad; } set {_Edad=value;} } public Persona( ) {} public Persona(string pNombre, int pEdad) { Nombre = pNombre ; Edad = pEdad; } } Y la siguiente interfase de usuario que muestra los datos de una instancia de la clase Persona y permite modificar la edad cada vez que se presiona el botn de Cumpleaos: <Window x:Class="Notificaciones.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Window1" Height="300" Width="300" Loaded="Window_Loaded"> <Grid VerticalAlignment="Top" HorizontalAlignment="Left" Width="250" Height="100"> <Grid.ColumnDefinitions > <ColumnDefinition /> <ColumnDefinition /> </Grid.ColumnDefinitions> <Grid.RowDefinitions > <RowDefinition /> <RowDefinition /> <RowDefinition /> 70

</Grid.RowDefinitions> <TextBlock Grid.Row="0" Grid.Column="0" >Nombre:</TextBlock> <TextBox Grid.Row="0" Grid.Column="1" Height="23" Name="txtNombre" /> <TextBlock Grid.Row="1" Grid.Column="0">Edad:</TextBlock> <TextBox Name="txtEdad" Grid.Row="1" Grid.Column="1" Height="23"/> <Button Grid.Row="2" Grid.ColumnSpan="2" Name="btnCumple" Click="btnCumple_Click">Cumpleaos</Button> </Grid> </Window>

public partial class Window1 : Window { Persona oPersona; public Window1() { InitializeComponent(); } private void Window_Loaded(object sender, RoutedEventArgs e) { oPersona = new Persona("Juan", 10); txtNombre.Text = oPersona.Nombre; txtEdad.Text = oPersona.Edad.ToString(); } private void btnCumple_Click(object sender, RoutedEventArgs e) { oPersona.Edad++; MessageBox.Show("Feliz Cumpleaos"); // Actualizamos manualmente la propiedad txtEdad.Text = oPersona.Edad.ToString(); } } Este ejemplo funciona perfectamente, pero como no tiene sincronizados los valores del oPersona con los TextBoxs estos tienen que actualizarse manualmente cada vez que se genera un cambio en alguno de los dos valores. Una forma para que la UI lleve registro de los cambios, mejor que la del ejemplo anterior, es que el objeto avise cuando una propiedad cambia, por ejemplo, lanzando un evento. La forma correcta de hacer esto, es que el objeto implemente INotifyPropertyChanged. using System.ComponentModel. public class Persona: INotifyPropertyChanged { ...... #region Miembros de INotifyPropertyChanged public event PropertyChangedEventHandler PropertyChanged; #endregion } De esta manera deberamos entonces agregar a la clase Persona las siguientes lneas. Estas lneas agregan un evento a la clase llamado PropertyChanged y el mismo es disparado a 71

travs del mtodo Notificar, que es invocado por los Set de las propiedades, reflejando el cambio. public class Persona: INotifyPropertyChanged { private string _Nombre; public string Nombre { get { return _Nombre; } set { _Nombre = value; Notificar ("Nombre"); } } int _Edad; public int Edad { get { return _Edad; } set { _Edad=value; Notificar ("Edad"); } } public Persona( ) {} public Persona(string pNombre, int pEdad) { Nombre = pNombre ; Edad = pEdad; } public event PropertyChangedEventHandler PropertyChanged; protected void Notificar (string NombrePropiedad) { if (this.PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(NombrePropiedad)); } } } El cdigo de la ventana quedara de la siguiente manera. Atajamos el evento disparado por la clase Persona y adems necesitaramos tambin un mecanismo que detecte los cambios en la interfase grfica, y los propague hacia el objeto, de manera que la sincronizacin sea en ambos sentidos. Para ellos atajamos el evento TextChanged de los TextBox y modificamos el valor de las propiedades. De esta manera mantenemos ambos valores sincronizados permanentemente.

72

public partial class Window1 : Window { Persona oPersona; public Window1() { InitializeComponent(); } private void Window_Loaded(object sender, RoutedEventArgs e) { oPersona = new Persona("Juan", 10); txtNombre.Text = oPersona.Nombre; txtEdad.Text = oPersona.Edad.ToString(); oPersona.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler( Persona_PropertyChanged); } private void btnCumple_Click(object sender, RoutedEventArgs e) { oPersona.Edad++; MessageBox.Show("Feliz Cumpleaos"); } private void Persona_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) { switch( e.PropertyName ) { case "Nombre": txtNombre.Text = oPersona.Nombre; break; case "Edad": txtEdad.Text = oPersona.Edad.ToString(); break; } } private void txtNombre_TextChanged(object sender, TextChangedEventArgs e) { oPersona.Nombre = txtNombre.Text; } private void txtEdad_TextChanged(object sender, TextChangedEventArgs e) { oPersona.Edad = System.Convert.ToInt32(txtEdad.Text); } }

Sin importar entonces en donde se de el cambio (objeto ,UI), ambos elementos se mantienen sincronizados. Claramente, la cantidad de cdigo a escribir puede llegar a ser importante si la cantidad de objetos, propiedades de los objetos y eventos aumenta. Adems, este tipo de tareas parecen 73

bastante repetitivas. Por eso es que WPF las abstrae en funcionalidades del framework, dndole el nombre de Data Binding.

3- Convertir Datos
ValueConverters Si se desea enlazar dos propiedades de diferente tipo se deber usar un ValueConverter. Los ValueConventer convierten los valores del tipo de dato de la fuente al tipo de dato del destino o viceversa. Para generar clases convertidora personalizadas es necesario usar la interfase IValueConverter

Interfase IValueConverter Esta interfase permite generar clases que apliquen cdigo de conversin de datos que pueden usarse en enlaces de datos. Para ellos cree una nueva clase e implemente la interfase IValueConverter. Esta interfase contiene dos mtodos Convert y ConvertBack. Esta clase podr convertir los datos de un tipo de dato a otro o modificar el aspecto de la presentacin. Ambos mtodos estn asociados a culturas. Si el uso de culturas no es necesario en la aplicacin con la cual se est trabajando este parmetro puede ignorarse. Por ejemplo si necesitamos enlazar un valor verdadero o falso a la propiedad Visibility debemos convertir el dato, ya que esta propiedad es una enumeracin que contiene tres valores: Visible, Collapsed o Hidden. Como primer paso escribiremos una clase que implemente a la interfase IValueConverter y que implemente el mtodo Convert de manera de generar la conversin necesaria. En este ejemplo no se est permitiendo la conversin inversa. using System.Windows.Data; using System.Globalization; using System.Windows; public class ConversionBooleanToVisibility: IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (value is Boolean) { return ((bool)value) ? Visibility.Visible : Visibility.Collapsed; } return value; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 74

{ throw new NotImplementedException(); } } Luego crearemos un recurso que nos permita relacionar esta ventana con la clase. Al momento del enlace usando el atributo Converter podemos generar la llamada a nuestro convertidor. <Window x:Class="WpfCSharp.Window2" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Window2" Height="200" Width="300" xmlns:svc="clr-namespace:WpfCSharp" > <StackPanel> <StackPanel.Resources> <svc:ConversionBooleanToVisibility x:Key="boolToVisible" /> </StackPanel.Resources> <CheckBox x:Name="chkPrueba" Content="Prueba Visibilidad" /> <StackPanel x:Name="Detalle" Visibility="{Binding IsChecked, ElementName=chkPrueba, Converter={StaticResource boolToVisible}}"> <Button Height="23" Width="50" Content="Prueba"></Button> </StackPanel> </StackPanel> </Window>

En el siguiente ejemplo se crea una clase para controlar la validacin y formateo de datos de tipo fecha. Al escribir una fecha sobre el TextBox, cuando reconoce que lo escrito tiene un formato tipo fecha la devuelve en formato dd/mm/aaaa en el TextBlock [ValueConversion(typeof(DateTime), typeof(String))] public class ConvierteFecha : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { DateTime fecha; if (value != null && DateTime.TryParse(value.ToString(), out fecha)) { return fecha.ToString("dd/MM/yyyy"); 75

} else return ""; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { string strValue = (string)value; DateTime fecha; if (DateTime.TryParse(strValue, out fecha)) return fecha; else throw new NotImplementedException(); } } <Window.Resources > <svc:ConvierteFecha x:Key="ConvFecha" /> </Window.Resources> <StackPanel> <TextBox Name="txtFecha" /> <TextBlock Name="tbFecha" Text="{Binding ElementName=txtFecha, Path=Text, Converter={StaticResource ConvFecha}}" /> <Button Height="20" Width="100" Content="Aceptar"></Button> </StackPanel>

El atributo ValueConversion permite especificar el tipo de dato de entrada y el de salida, es til para documentar el tipo de conversin que estamos realizando, pero no es obligatorio su uso para que la conversin funcione correctamente.

4- Validar Datos
ValidationRules La clase Binding cuenta con una propiedad llamada ValidationRules, que puede almacenar varias clases derivadas de ValidationRule. Todas esas reglas pueden contener cierta lgica que intenta comprobar si el valor enlazado es vlido. Se pueden crear reglas personalizadas creando clases que deriven de ValidationRule o usar la clase ExceptionValidationRule que invalida el dato si existen excepciones durante el enlace. 76

Clase Binding.ValidationRule Permite crear reglas personalizadas de manera de poder validar el ingreso de datos enlazados. En el siguiente ejemplo se crear una clase que valida el rango de edad aceptado en una aplicacin. Valida que solo se ingresen nmeros y que el rango est entre dos valores que pueden establecerse a travs de propiedades. public class ReglaEdad: ValidationRule { private int _minEdad; public int MinEdad { get { return _minEdad; } set { _minEdad = value; } } private int _maxEdad; public int MaxEdad { get { return _maxEdad; } set { _maxEdad = value; } } public override ValidationResult Validate(object value, CultureInfo cultureInfo) { int iEdad = 0; try { if (((string)value).Length > 0) iEdad = Int32.Parse((String)value); } catch (Exception e) { return new ValidationResult(false, "Carcter incorrecto o " + e .Message); } if ((iEdad < MinEdad) || (iEdad > MaxEdad)) { return new ValidationResult(false, "Por favor ingrese la edad en el rango: " + MinEdad + " - " + MaxEdad + "."); } else { return new ValidationResult(true, null); } } } Se crea tambin una clase llamada GenerarPersonas que devuelve un objeto Persona (definido en el punto 2 de este mismo captulo). La llamada a este mtodo generar la fuente de datos para el enlace. 77

public class GenerarPersonas { public Persona TraerPersona() { Persona oPersona = new Persona(); oPersona.Nombre = "Juan"; oPersona.Edad = 1; return oPersona; } } Enlazamos entonces la propiedad Edad del objeto Persona a un TextBox llamado tbEdad. Tambin le asociamos la regla ReglaEdad y le damos valor a las propiedades MaxEdad y MinEdad de manera que establecer el rango. <TextBox Name="tbEdad" DataContext="{StaticResource Datos}" Width="100"> <TextBox.Text> <Binding Path="Edad" UpdateSourceTrigger="PropertyChanged" > <Binding.ValidationRules> <svc:ReglaEdad MinEdad="1" MaxEdad="80" /> </Binding.ValidationRules> </Binding> </TextBox.Text> </TextBox> Creamos una plantilla y su estilo asociado para poder marcar los TextBox con error mostrando un punto rojo a la derecha del mismo y el mensaje de error en un ToolTip. <Window.Resources> <ObjectDataProvider x:Key="Datos" ObjectType="{x:Type svc:GenerarPersonas}" MethodName="TraerPersona"></ObjectDataProvider> <ControlTemplate x:Key="TextBoxErrorTemplate"> <DockPanel> <Ellipse DockPanel.Dock="Right" Margin="2,0" Width="10" Height="10"> <Ellipse.Fill> <LinearGradientBrush> <GradientStop Color="#11FF1111" Offset="0" /> <GradientStop Color="#FFFF0000" Offset="1" /> </LinearGradientBrush> </Ellipse.Fill> </Ellipse> <AdornedElementPlaceholder /> </DockPanel> </ControlTemplate> <Style x:Key="EstiloError" TargetType="TextBox"> <Setter Property="Margin" Value="4,4,10,4" /> <Setter Property="Validation.ErrorTemplate" Value="{StaticResource TextBoxErrorTemplate}" /> <Style.Triggers> <Trigger Property="Validation.HasError" Value="True"> <Setter Property="ToolTip"> <Setter.Value> 78

<Binding Path="(Validation.Errors)[0].ErrorContent" RelativeSource="{x:Static RelativeSource.Self}" /> </Setter.Value> </Setter> </Trigger> </Style.Triggers> </Style> </Window.Resources> <StackPanel> <TextBox Name="tbEdad" DataContext="{StaticResource Datos}" Style="{StaticResource EstiloError}" Width="100"> <TextBox.Text> <Binding Path="Edad" UpdateSourceTrigger="PropertyChanged" > <Binding.ValidationRules> <svc:ReglaEdad MinEdad="1" MaxEdad="80" /> </Binding.ValidationRules> </Binding> </TextBox.Text> </TextBox> <Button Height="20" Width="100" Content="Aceptar"></Button> </StackPanel>

IDataErrorInfo Con la llegada de Microsoft .NET Framework 3.5, la compatibilidad de WPF para la validacin de entradas ha mejorado significativamente. ValidationRule es de utilidad para las validaciones sencillas, pero las aplicaciones del mundo real se enfrentan a la complejidad de los datos y las reglas de negocio. La codificacin de reglas de negocio en objetos ValidationRule no slo vincula dicho cdigo a la plataforma WPF, sino que adems no permite que haya lgica de negocio ah donde debe existir: en los objetos de negocios. Muchas aplicaciones tienen una capa de negocio, en la que la complejidad del procesamiento de reglas de negocio se incluye en un conjunto de objetos de negocios. Al compilar en Microsoft .NET Framework 3.5, puede usar la interfase IDataErrorInfo para que WPF pregunte a los objetos de negocios si estn en un estado vlido o no. De esta forma, se elimina la necesidad de agregar a los objetos una lgica de negocio independiente desde la capa de negocio, y permite crear objetos de negocios independientes de la plataforma de la interfase de usuario. Dado que la interfase IDataErrorInfo existe desde hace aos, se facilita en gran medida el uso repetido de objetos de negocios de una aplicacin heredada de Windows Forms o ASP.NET. IDataErrorInfo implementa 2 propiedades: Error: Devuelve el mensaje de error indicando lo que no es correcto en el objeto 79

Item: Devuelve el mensaje de error para la propiedad

Para el ejemplo tomaremos la misma clase Persona del ejemplo anterior y en ella implementaremos la interfase IDataErrorInfo. using System.ComponentModel; public class Persona : IDataErrorInfo { private string _Nombre; public string Nombre { get { return _Nombre; } set { _Nombre = value; } } int _Edad; public int Edad { get { return _Edad; } set { _Edad = value; } } public Persona() { } public Persona(string pNombre, int pEdad) { Nombre = pNombre; Edad = pEdad; } public string Error { get { throw new NotImplementedException(); } } public string this[string columnName] { get { string result = null; if (columnName == "Nombre") { if (String.IsNullOrEmpty(Nombre)) result = "Debe ingresar el nombre"; else if (Nombre.Length < 3) result = "El nombre debe tener al menos 3 carcteres"; } else if (columnName == "Edad") { // Verifica rango if ((Edad < 1) || (Edad > 80)) { result="El edad debe estar entre 1 y 80"; } 80

} return result; } } } Teniendo en cuenta las mismas fuentes de datos, plantilla y estilo del ejemplo anterior modificamos el cdigo para que valide usando las propiedades de esta interfase. <StackPanel> <TextBox Name="txtNombre" DataContext="{StaticResource Datos}" Style="{StaticResource EstiloError}" Width="100"> <TextBox.Text> <Binding Path="Nombre" UpdateSourceTrigger="PropertyChanged"> <Binding.ValidationRules> <ExceptionValidationRule /> <DataErrorValidationRule /> </Binding.ValidationRules> </Binding> </TextBox.Text> </TextBox> <TextBox Name="txtEdad" DataContext="{StaticResource Datos}" Style="{StaticResource EstiloError}" Width="100"> <TextBox.Text> <Binding Path="Edad" UpdateSourceTrigger="PropertyChanged" ValidatesOnExceptions="true" ValidatesOnDataErrors="true" /> </TextBox.Text> </TextBox> <Button Height="20" Width="100" Content="Aceptar"></Button> </StackPanel>

ValidatesOnExceptions indica si debe incluirse o no ExceptionValidationRule. ValidatesOnDataErrors indica si debe incluirse o no DataErrorValidationRule, por lo tanto el cdigo usado en ambos TextBox es idntico, con diferente sintaxis.

ExceptionValidationRule Representa la regla que verifica las excepciones que son disparadas durante las modificaciones de las propiedades enlazadas. DataErrorValidationRule Representa la regla que verifica los errores disparados por la implementacin de IDataErrorInfo. 81

Mdulo 5

Enlace a Colecciones

82

1- Enlace a Colecciones
Enlace a Colecciones Un objeto de origen del enlace se puede tratar como un objeto nico cuyas propiedades contienen los datos, o como una recoleccin de datos de objetos polimrficos que suelen estar agrupados (como el resultado de una consulta a una base de datos). Por ejemplo, es habitual utilizar ItemsControl como ListBox, ListView o TreeView para mostrar una recoleccin de datos. La propiedad que se utiliza es ItemsSource. Puede considerar la propiedad ItemsSource como el contenido del ItemsControl. El enlace ser OneWay porque la propiedad ItemsSource admite el enlace OneWay de forma predeterminada.

Cmo implementar colecciones Es posible enumerar cualquier coleccin que implementa la interfase IEnumerable. Sin embargo, para configurar enlaces dinmicos de modo que las inserciones o eliminaciones que se realicen en la coleccin actualicen la interfase de usuario de forma automtica, la coleccin debe implementar la interfase INotifyCollectionChanged. Esta interfase expone un evento que debe provocarse siempre que se realicen cambios en la coleccin subyacente. public event PropertyChangedEventHandler PropertyChanged; WPF proporciona la clase ObservableCollection<T>, que es una implementacin integrada de una recoleccin de datos que expone la interfase INotifyCollectionChanged. Observe que para permitir totalmente la transferencia de valores de datos de los objetos de origen a los destinos, cada objeto de la coleccin que admite propiedades enlazables debe implementar tambin la interfase INotifyPropertyChanged. Antes de implementar su propia coleccin, considere la posibilidad de utilizar ObservableCollection<T> o una de las clases de coleccin existentes, como List<T>, Collection<T> y BindingList<T>, entre otras muchas. Si cuenta con un escenario avanzado y desea implementar su propia coleccin, considere la posibilidad de utilizar IList, que proporciona una coleccin no genrica de objetos a los que se puede obtener acceso individualmente por ndice y, por consiguiente, proporciona el mximo rendimiento. En el siguiente ejemplo se muestra un ListBox enlazado a una objeto List<>. private void Window_Loaded(object sender, RoutedEventArgs e) { List<string> Lista = new List<string>(); Lista.Add("Buenos Aires"); Lista.Add("Crdoba"); Lista.Add("Mendoza"); stpProv.DataContext = Lista; } 83

<StackPanel Name="stpProv"> <ListBox Name="lstProv" ItemsSource="{Binding}" /> </StackPanel>

En el siguiente ejemplo se implementa una clase personalizada que implementa la interfase INotifyPropertyChanged que se usar para armar una coleccin enlazable. using System.ComponentModel; using System.Collections.ObjectModel; public class Empleado : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private string _Nombre; public string Nombre { get { return _Nombre; } set { _Nombre = value; OnPropertyChanged("Nombre"); } } private string _Apellido; public string Apellido { get { return _Apellido; } set { _Apellido = value; OnPropertyChanged("Apellido"); } } public Empleado(string pNombre, string pApellido) { Nombre = pNombre; Apellido = pApellido; } protected void OnPropertyChanged(string info) { PropertyChangedEventHandler handler = PropertyChanged; if (handler != null) 84

{ handler(this, new PropertyChangedEventArgs(info)); } } public override string ToString() { return Apellido.ToString() + ", " + Nombre.ToString(); } } Ahora creamos otra clase que deriva de ObservableCollection<> y desde el constructor ingresamos los datos a la coleccin. public class Empleados : ObservableCollection<Empleado> { public Empleados() { Add(new Empleado("Juan", "Perez")); Add(new Empleado("Jose", "Lopez")); Add(new Empleado("Maria", "Rodriguez")); } }

Creamos un recurso a la clase que contiene los datos de la coleccin y generamos el enlace en un ListBox <Window x:Class="WpfCSharp.Window2" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Height="300" Width="500" xmlns:svc="clr-namespace:WpfCSharp" Title="Enlazar a una Coleccin" SizeToContent="WidthAndHeight"> <Window.Resources> <svc:Empleados x:Key="Empleados"/> </Window.Resources> <StackPanel> <TextBlock FontFamily="Verdana" FontSize="11" Margin="5,15,0,10" FontWeight="Bold">Empleados de la Empresa</TextBlock> <ListBox Width="200" IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding Source={StaticResource Empleados}}"/> </StackPanel> </Window>

85

2- Vistas de Colecciones
Vistas de colecciones Una vez que ItemsControl est enlazado a una recoleccin de datos, quizs desee ordenar, filtrar o agrupar los datos. Para ello, se utilizan vistas de coleccin, que son clases que implementan la interfase ICollectionView. Una vista de coleccin es un nivel situado encima de la coleccin de origen del enlace, que le permite navegar y mostrar la coleccin de origen en funcin de las consultas de ordenamiento, filtrado y agrupacin, sin tener que cambiar la propia coleccin de origen subyacente. Una vista de coleccin tambin contiene un puntero al elemento actual de la coleccin. Si la coleccin de origen implementa la interfase INotifyCollectionChanged, los cambios provocados por el evento CollectionChanged se propagarn a las vistas. Dado que las vistas no cambian las colecciones de origen subyacente, cada coleccin de origen puede tener varias vistas asociadas. El uso de vistas le permite mostrar los mismos datos de formas diferentes. Por ejemplo, en el lado izquierdo de la pgina es posible que desee mostrar las tareas ordenadas por prioridad y, en el lado derecho, agrupadas por rea.

Cmo crear una vista Una manera de crear y utilizar una vista es crear directamente una instancia del objeto de vista y utilizar a continuacin esa instancia como el origen del enlace. Para crear otra vista para la misma coleccin, puede crear otra instancia de CollectionViewSource y asignarle un nombre x:Key diferente. Especificar una vista de coleccin como origen de enlace es una forma de crear y utilizar una vista de coleccin. WPF tambin crea una vista de coleccin predeterminada para cada coleccin utilizada como origen de enlace. Si enlaza directamente a una coleccin, WPF enlaza a su vista predeterminada. Tenga en cuenta que todos los enlaces a una misma coleccin comparten esta vista predeterminada, de modo que si se realiza un cambio en una vista predeterminada a travs de un control enlazado o mediante cdigo (como un cambio de ordenacin o en el puntero de elemento actual, que se describe ms adelante), ste se refleja en el resto de los enlaces a la misma coleccin. Para obtener la vista predeterminada, se utiliza el mtodo GetDefaultView.

Ordenar Las vistas pueden aplicar un criterio de orden a una coleccin. Cuando este criterio existe en la coleccin subyacente, los datos pueden o no tener un orden relevante. La vista de la coleccin le permite aplicar un orden o cambiar el orden predeterminado, en funcin de los criterios de comparacin especificados. Con las vistas, se puede aplicar ordenamientos controlados por el usuario, sin tener que realizar ningn cambio en la coleccin subyacente ni tener tampoco que volver a consultar el contenido de la coleccin. El ordenamiento se realiza usando la propiedad CollectionViewSource.SortDescriptions. Para mejorar el rendimiento, las vistas de coleccin para objetos DataTable o DataView de ADO.NET delegan el ordenamiento y el filtrado a DataView. Esto hace que todas las vistas de coleccin del origen de datos compartan el ordenamiento y el filtrado. Para habilitar el ordenamiento y el filtrado independientes de cada vista de coleccin, inicialice cada vista de este tipo con su propio objeto DataView. El siguiente ejemplo permite ordenar los datos de la coleccin Empleados del ejemplo anterior por el campo Apellido y mostrarlos en un ListBox <Window x:Class="WpfCSharp.Window2" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 86

Height="300" Width="500" xmlns:svc="clr-namespace:WpfCSharp" xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase" Title="Enlazar a una Coleccin" SizeToContent="WidthAndHeight"> <Window.Resources> <svc:Empleados x:Key="Empleados"/> <CollectionViewSource Source="{StaticResource Empleados}" x:Key="EmplOrdenados"> <CollectionViewSource.SortDescriptions> <scm:SortDescription PropertyName="Apellido"/> </CollectionViewSource.SortDescriptions> </CollectionViewSource> </Window.Resources> <StackPanel> <TextBlock FontFamily="Verdana" FontSize="11" Margin="5,15,0,10" FontWeight="Bold">Empleados de la Empresa</TextBlock> <ListBox Width="200" IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding Source={StaticResource EmplOrdenados}} "/> </StackPanel> </Window>

Agrupar Todas las vistas de coleccin admiten la funcionalidad de agrupacin, que permite al usuario dividir la coleccin en la vista de coleccin en grupos lgicos. Los grupos pueden ser explcitos, donde el usuario proporciona una lista de grupos, o implcitos, donde los grupos se generan dinmicamente en funcin de los datos. La agrupacin se realiza usando la propiedad CollectionViewSource.GroupDescriptions. Teniendo en cuenta el ejemplo anterior agregamos una nueva propiedad en la clase llamada Ciudad de manera de organizar a los empleados en su lugar de trabajo. El ejemplo permite mostrar a los empleados organizados por ciudad public class Empleado : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private string _Nombre; public string Nombre { get { return _Nombre; } set { _Nombre = value; OnPropertyChanged("Nombre"); } 87

} private string _Apellido; public string Apellido { get { return _Apellido; } set { _Apellido = value; OnPropertyChanged("Apellido"); } } private string _Ciudad; public string Ciudad { get { return _Ciudad; } set { _Ciudad = value; OnPropertyChanged("Ciudad"); } } public Empleado(string pNombre, string pApellido, string pCiudad) { Nombre = pNombre; Apellido = pApellido; Ciudad = pCiudad; } protected void OnPropertyChanged(string info) { PropertyChangedEventHandler handler = PropertyChanged; if (handler != null) { handler(this, new PropertyChangedEventArgs(info)); } } public override string ToString() { return Apellido.ToString() + ", " + Nombre.ToString(); } } public class Empleados : ObservableCollection<Empleado> { public Empleados() { Add(new Empleado("Juan", "Perez", "Buenos Aires")); Add(new Empleado("Jose", "Lopez","Mendoza")); Add(new Empleado("Maria", "Rodriguez", "Buenos Aires")); Add(new Empleado("Carlos", "Diaz", "Buenos Aires")); Add(new Empleado("Mariana", "Fernandez", "Mendoza")); 88

} }

<Window x:Class="WpfCSharp.Window2" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Height="300" Width="500" xmlns:svc="clr-namespace:WpfCSharp" xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase" Title="Enlazar a una Coleccin" SizeToContent="WidthAndHeight"> <Window.Resources> <svc:Empleados x:Key="Empleados"/> <CollectionViewSource Source="{StaticResource Empleados}" x:Key="EmplOrdenados"> <CollectionViewSource.SortDescriptions> <scm:SortDescription PropertyName="Apellido"/> </CollectionViewSource.SortDescriptions> <CollectionViewSource.GroupDescriptions> <PropertyGroupDescription PropertyName="Ciudad"/> </CollectionViewSource.GroupDescriptions> </CollectionViewSource> </Window.Resources> <StackPanel> <TextBlock FontFamily="Verdana" FontSize="11" Margin="5,15,0,10" FontWeight="Bold">Empleados de la Empresa</TextBlock> <ListBox Width="200" IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding Source={StaticResource EmplOrdenados}}" DisplayMemberPath="Apellido" Name="lb"> <ListBox.GroupStyle> <x:Static Member="GroupStyle.Default"/> </ListBox.GroupStyle> </ListBox> </StackPanel> </Window>

Filtrar Las vistas pueden aplicar tambin un filtro a una coleccin. Esto significa que aunque un elemento pueda existir en la coleccin, esta vista en concreto est destinada a mostrar nicamente determinado subconjunto de la coleccin completa. Los datos se filtran en funcin a condiciones usando la propiedad Filter. 89

El siguiente ejemplo aplica un filtro de manera de no mostrar todos los datos que estn sobre el ListBox en base al valor del CheckBox. Si el CheckBox esta tildado solo se muestran los empleados cuyo apellido empieza con P, si est destildado muestra todos los empleados. La propiedad Filter del objeto CollectionViewSource se asocia al mtodo que controla la condicin del filtro. <Window x:Class="WpfCSharp.Window2" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Height="300" Width="500" xmlns:svc="clr-namespace:WpfCSharp" xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase" Title="Enlazar a una Coleccin" SizeToContent="WidthAndHeight"> <Window.Resources> <svc:Empleados x:Key="dsEmpleados" /> <CollectionViewSource Source="{StaticResource dsEmpleados}" x:Key="EmplFiltrados" Filter="filtroP" /> </Window.Resources> <StackPanel> <TextBlock FontFamily="Verdana" FontSize="11" Margin="5,15,0,10" FontWeight="Bold">Empleados de la Empresa</TextBlock> <CheckBox Name="chkFiltro" IsChecked="True" Checked="chkFiltro_Checked" Unchecked="chkFiltro_Unchecked" >Empleados con P</CheckBox> <ListBox Width="200" IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding Source={ StaticResource EmplFiltrados}}" /> </StackPanel> </Window> public partial class Window2 : Window { CollectionViewSource EmplFilter; public Window2() { InitializeComponent(); EmplFilter = (CollectionViewSource)(this.Resources["EmplFiltrados"]); } private void filtroP(object sender, FilterEventArgs e) { Empleado oItem = (Empleado) e.Item; if (oItem.Apellido.StartsWith("P")) e.Accepted = true; else e.Accepted = false; } private void chkFiltro_Checked(object sender, RoutedEventArgs e) { if (EmplFilter != null) EmplFilter.Filter += new FilterEventHandler(filtroP); } private void chkFiltro_Unchecked(object sender, RoutedEventArgs e) { 90

if (EmplFilter != null) EmplFilter.Filter -= new FilterEventHandler(filtroP); } }

Punteros de elemento actual Las vistas admiten tambin la nocin de elemento actual. Puede navegar por los objetos en una vista de coleccin. A medida que navega por los objetos, mueve un puntero de elemento que le permite recuperar el objeto ubicado concretamente en esa posicin en la coleccin. Al enlazar a una vista, el carcter de barra diagonal ("/") de un valor Path designa el elemento actual de la vista. En el ejemplo siguiente, el contexto de datos es una vista de coleccin. La primera lnea enlaza a la coleccin. La segunda lnea enlaza al elemento actual de la coleccin. La tercera lnea enlaza a la propiedad Description del elemento actual de la coleccin. <Button Content="{Binding }" /> <Button Content="{Binding Path=/}" /> <Button Content="{Binding Path=/Description}" /> La nocin de elemento actual no es slo til para la navegacin de elementos en una coleccin, sino tambin para el escenario de enlace Cabecera-Detalle. Navegacin de Colecciones Cuando se enlaza datos a controles con propiedades que soportan un solo elemento de la coleccin es necesario poder navegar la misma. Este escenario es comn cuando tengo una ventana que muestra datos por registro en Labels o TextBoxs. Dado que solo es posible ver un solo registro es necesario poder navegar la coleccin de manera de ver todos sus elementos. Para navegar por controles se usa la interfase ICollectionView que contiene mtodos que permiten no solo la navegacin, sino tambin el ordenado, filtrado, etc. En este ejemplo creamos un DataContext con la coleccin Empleados del ejemplo anterior y agregamos botones para poder navegar la coleccin. <StackPanel Name="stp" > <TextBlock Text="{Binding Nombre}" Width="100" Height="23"/> <TextBlock Text="{Binding Apellido}" Width="100" Height="23"/> <StackPanel Orientation="Horizontal" > <Button Content="&lt;&lt;" Name="btnPrimero" Width="30" Click="btnPrimero_Click" /> <Button Content="&lt;" Name="btnAnterior" Width="30" Click="btnAnterior_Click" /> <Button Content="&gt;" Name="btnSiguiente" Width="30" Click="btnSiguiente_Click" /> <Button Content="&gt;&gt;" Name="btnUltimo" Width="30" Click="btnUltimo_Click" /> 91

</StackPanel> </StackPanel> private void Window_Loaded(object sender, RoutedEventArgs e) { // Crea la coleccin como DataContext del StackPanel stp.DataContext = new Empleados(); } private void btnAnterior_Click(object sender, RoutedEventArgs e) { CollectionView Vista = (CollectionView)CollectionViewSource.GetDefaultView(stp.DataContext); Vista.MoveCurrentToPrevious(); if (Vista.IsCurrentBeforeFirst) { Vista.MoveCurrentToLast(); } } private void btnSiguiente_Click(object sender, RoutedEventArgs e) { CollectionView Vista = (CollectionView)CollectionViewSource.GetDefaultView(stp.DataContext); Vista.MoveCurrentToNext(); if (Vista.IsCurrentAfterLast) { Vista.MoveCurrentToFirst(); } } private void btnPrimero_Click(object sender, RoutedEventArgs e) { CollectionView Vista = (CollectionView)CollectionViewSource.GetDefaultView(stp.DataContext); Vista.MoveCurrentToFirst(); } private void btnUltimo_Click(object sender, RoutedEventArgs e) { CollectionView Vista = (CollectionView)CollectionViewSource.GetDefaultView(stp.DataContext); Vista.MoveCurrentToLast(); }

92

Mdulo 6

Administrar Documentos

93

1- Documentos
Definicin Windows Presentation Foundation (WPF) proporciona una amplia gama de documentos que permiten la creacin de contenido de alta fidelidad diseado para facilitar su acceso y lectura con respecto a las generaciones anteriores de Windows. Adems de las mejoras en las funciones y en la calidad, WPF proporciona servicios integrados para la presentacin, empaquetado y seguridad de los documentos.

Tipos de documentos WPF divide los documentos en dos categoras generales basndose en su uso previsto Documentos Dinmicos Documentos Fijos Los documentos fijos estn diseados para las aplicaciones que requieren una presentacin "lo que ve es lo que imprime" (WYSIWYG) precisa, independiente del hardware de pantalla o de impresin utilizado. Los usos tpicos para los documentos fijos incluyen la creacin de publicaciones, el procesamiento de textos y el diseo de formularios, donde es vital que se respete el diseo de pgina original. Un documento fijo mantiene la colocacin posicional precisa de los elementos de contenido con independencia del dispositivo de pantalla o de impresin utilizado. Por ejemplo, una pgina de un documento fijo presentada en una pantalla de 96 ppp aparecer exactamente igual cuando se imprima en una impresora lser de 600 ppp o en una mquina tipogrfica fotogrfica de 4800 ppp. El diseo de la pgina permanece inalterado en todos los casos, aunque la calidad del documento se maximiza de acuerdo con las funciones de cada dispositivo. En comparacin, los documentos dinmicos estn diseados para optimizar su presentacin y legibilidad y son ptimos para su uso cuando la facilidad de lectura constituye el principal escenario de consumo del documento. En lugar de establecerse en un diseo predefinido, este tipo de documentos ajusta y recoloca dinmicamente su contenido basndose en las variables de tiempo de ejecucin, tales como el tamao de la ventana, la resolucin del dispositivo y las preferencias opcionales del usuario. Una pgina web constituye un ejemplo sencillo de un documento dinmico donde se da formato al contenido de la pgina dinmicamente para ajustarlo a la ventana activa. Los documentos dinmicos optimizan la experiencia de visualizacin y lectura del usuario, basndose en el entorno de tiempo de ejecucin. Por ejemplo, el mismo documento dinmico cambiar su formato dinmicamente para aportar una legibilidad ptima en una pantalla de 19 pulgadas de alta resolucin o en la pequea pantalla de un PDA de 2 x 3 pulgadas. Adems, los documentos dinmicos tienen varias caractersticas integradas que incluyen la bsqueda, modos de presentacin que optimizan la legibilidad y la capacidad de cambiar el tamao y aspecto de las fuentes.

2- Documentos Dinmicos (FlowDocuments)


Definicin Los documentos dinmicos o FlowDocuments son documentos que pueden ser creados y mostrados en una aplicacin WPF. Consisten primordialmente en textos, con figuras y otros elementos incluidos en el entorno. Consisten de dos diferentes tipos de elementos: Elementos en bloque, los cuales definen bloques de secciones de texto, siempre tienen un salto de lnea entre cada elemento Elementos en lnea, que proveen formatos y efectos de texto en lnea. Para crearlos se usa el elemento FlowDocument. Estos documentos deben ser creados dentro de un contenedor, adems los contenedores nos proveen de Zoom, Paginacin, columnas y cuando se cambia de tamao, el texto se adecua al tamao del elemento. 94

Contenedores para Documentos Dinmicos Existen 3 tipos de contenedores: FlowDocumentScrollViewer: Este contenedor cuadra todo su contenido de acuerdo a su tamao y agrega barras de desplazamiento. Es el contenedor ms sencillo, aunque este tambin permite Zoom. Para aadir el Zoom al FlowDocumentScrollViewer, solo debemos dejar la propiedad de IsToolBarVisible a True. FlowDocumentPageViewer: Automticamente divide el contenido en pginas, el tamao de la pgina est determinado por el tamao del contenedor, incluye tambin un control para la paginacin, y un elemento Slider para el Zoom FlowDocumentReader: Es el contenedor que ms opciones tiene. Nos permite cambiar las vistas para la paginacin, adiciona barras de desplazamiento, columnas, una barra de bsqueda y Zoom.

FlowDocumentScrollViewer <FlowDocumentScrollViewer IsToolBarVisible="true"> <FlowDocument> <Paragraph> Este es una prueba de FlowDocument dentro de un FlowDocumentScrollViewer </Paragraph> </FlowDocument> </FlowDocumentScrollViewer>

FlowDocumentPageViewer <FlowDocumentPageViewer> <FlowDocument> <Paragraph> Este es una prueba de FlowDocument dentro de un FlowDocumentPageViewer </Paragraph> </FlowDocument> </FlowDocumentPageViewer>

95

FlowDocumentReader <FlowDocumentReader > <FlowDocument> <Paragraph> Este es una prueba de FlowDocument dentro de un FlowDocumentReader </Paragraph> </FlowDocument> </FlowDocumentReader>

Formateando Documentos Dinmicos Todos los elementos en lnea y en bloques tienen muchas propiedades que podemos usar para formatear el texto, como por ejemplo el fondo, el color, tipo, tamao, estilo de la letra entre otras. Los cambios hechos a dichas propiedades son aplicados a todo el texto que esta encerrado en el elemento, hay otras propiedades que solo aplican para los elementos en bloque y son: color, grosor del borde, espaciamiento del texto, mrgenes, alineacin del texto. Si en el primer ejemplo cambiamos la siguiente lnea a <Paragraph Background="yellow" BorderBrush="Red" BorderThickness="4" Foreground="Green" > El documento quedar:

Elementos en Bloque Como hemos visto, los elementos en bloque acomodan el texto dentro del documento, entre estos elementos tenemos: Paragraph: Este es el ms bsico de los elementos en bloque y definen un bloque de texto dentro de un prrafo. Puede haber varios prrafos en un documento. 96

List: El elemento List permite definir una lista de elementos. Cada elemento debe estar dentro de un elemento ListItem, y los ListItem deben contener otro elemento como por ejemplo un Paragraph. Table: El elemento Table es muy parecido al Table de HTML, para crear una tabla, se crea un elemento Table, que tendr como hijo un elemento TableRowGroup, en el TableRowGroup habr una coleccin de elementos TableRow, y los elementos TableRow tendrn a su vez una coleccin de elementos TableCell el cul tendr el contenido de una celda, como por ejemplo un elemento Paragraph. Section: El elemento Section es til para agrupar otros elementos bloque, por ejemplo podemos tener una seccin de muchos prrafos con un estilo y otra seccin con otros estilos en el mismo documento. BlockUIContainer: Permite incorporar otros elementos UIElement, como un Button, un ListBox y otros.

List <FlowDocumentScrollViewer> <FlowDocument> <List> <ListItem> <Paragraph>Buenos Aires</Paragraph> </ListItem> <ListItem> <Paragraph>Mendoza</Paragraph> </ListItem> <ListItem> <Paragraph>Crdoba</Paragraph> </ListItem> <ListItem> <Paragraph>San Juan</Paragraph> </ListItem> <ListItem> <Paragraph>San Luis</Paragraph> </ListItem> </List> </FlowDocument> </FlowDocumentScrollViewer>

La propiedad MarketStyle permite configurar las vietas. Los valores posibles son: Box, Circle, Decimal, Disc, LowerLatin, LowerRoman, None, UpperLatin, UpperRoman. <List MarkerStyle="Decimal" >

97

Tabla <FlowDocumentScrollViewer> <FlowDocument> <Table BorderBrush="Black"> <TableRowGroup> <TableRow> <TableCell ColumnSpan="4" TextAlignment="Center"> <Paragraph FontSize="16pt" FontWeight="Bold">Ejemplo tabla</Paragraph> </TableCell> </TableRow> <TableRow FontWeight="Bold" Foreground="Red" > <TableCell> <Paragraph>Visitas</Paragraph> </TableCell> <TableCell> <Paragraph>IP</Paragraph> </TableCell> </TableRow> <TableRow Background="White"> <TableCell> <Paragraph>100</Paragraph> </TableCell> <TableCell> <Paragraph>127.0.0.1</Paragraph> </TableCell> </TableRow> <TableRow> <TableCell> <Paragraph>100</Paragraph> </TableCell> <TableCell> <Paragraph>127.0.0.1</Paragraph> </TableCell> </TableRow> </TableRowGroup> </Table> </FlowDocument> </FlowDocumentScrollViewer>

98

Section <FlowDocumentScrollViewer> <FlowDocument> <Section FontStyle="Italic"> <Paragraph>Escribimos este prrafo en letra italic</Paragraph> </Section> <Section Foreground="red"> <Paragraph>Este prrafo esta escrito en rojo</Paragraph> </Section> </FlowDocument> </FlowDocumentScrollViewer>

BlockUIContainer <FlowDocument> <Section FontStyle="Italic"> <Paragraph>Prrafo en letra italic para probar FlowDocuments.</Paragraph> </Section> <BlockUIContainer> <Button Width="500" Height="23" HorizontalAlignment="Center">clic para ms informacin</Button> </BlockUIContainer> </FlowDocument>

99

Elementos en Lnea (Contenido dinmico) Los elementos dinmicos envuelven texto dentro de bloques, son usados para dar formato a los textos, como crear hipervnculos, aplicar propiedades como negrita a una parte del texto, y otras. Run: El elemento run, contiene texto normal, cuando no se crea ningn elemento dinmico, el elemento Run es aplicado implcitamente al texto Bold, Italic y Underline: Estos elementos aplicados a un texto dan el formato de negrita, cursiva y subrayado. Hyperlink: Agrega un hipervnculo al texto LineBreak: Provoca un salto de lnea, este elemento no soporta contenido directo. Floater: Permite crear una seccin del documento que es paralela con el flujo principal de otro contenido, es til para las imgenes. InlineUIContainer: Permite insertar elementos UIElement, dentro del elemento dinmico, es parecido al BlockUIContainer. <FlowDocument> <Paragraph>Un ejemplo del los elementos <Bold>Bold</Bold> , <Italic>Italic</Italic> y <Underline>Underline.</Underline> <LineBreak/> Aca sigue el prrafo <LineBreak/> </Paragraph> <Paragraph>Probando Hyperlink <Hyperlink>http://www.microsoft.com</Hyperlink> <InlineUIContainer> <Button Width="100" Height="23">Presionar</Button> </InlineUIContainer> </Paragraph> </FlowDocument>

<FlowDocument> <Paragraph> Este es un prrafo normal. 100

<Floater FontFamily="TimesNewRoman" FontSize="12" Width="100" HorizontalAlignment="Left"> <Paragraph>Este prrafo esta escrito con Floater</Paragraph> </Floater> <LineBreak/> Y Esta parte del prrafo comparte el rengln con el prrafo armado con Floater. </Paragraph> </FlowDocument>

3- Documentos Fijos
Definicin Hospeda un documento portable, de formato fijo y alta fidelidad con acceso de lectura para la seleccin de texto de usuario, navegacin mediante teclado y bsqueda. Para crearlos se usa el elemento FixedDocument que enlaza lgicamente una secuencia ordenada de pginas en un documento nico, de varias pginas y diseo fijo. PageContent es el nico elemento secundario permitido del elemento FixedDocument. Cada elemento PageContent hace referencia al origen del contenido para una pgina nica. Los elementos PageContent deben estar en orden de marcado secuencial, coincidiendo con el orden de pgina del documento. FixedDocument est diseado para aplicaciones "lo que ve es lo que imprime" (WYSIWYG) donde la aplicacin define y controla el diseo del documento a fin de representar con la mxima exactitud la pantalla o el dispositivo de impresin.

PageContent Proporciona informacin sobre los elementos FixedPage dentro de FixedDocument sin exigir a la aplicacin que cargue pginas individuales. Los elementos PageContent son los nicos elementos secundarios permitidos de FixedDocument. El orden de los elementos PageContent dentro de FixedDocument define el orden de las pginas. La propiedad de dependencia Source especifica el identificador de recursos uniforme (URI) del objeto FixedPage correspondiente. Nota: El diseador de WPF no soporta el ingreso del elemento <PageContent>. El programa ejecuta pero el diseador genera un error que dice: Property 'Pages' does not support values of type 'PageContent'. Es un bug que est documentado y que probablemente va a ser solucionado en la versin 2010. FixedPage Proporciona el contenido de una pgina de formato fijo de alta fidelidad. FixedPage se utiliza normalmente para proporcionar el contenido de una pgina dentro de FixedDocument. 101

FixedPage define automticamente saltos de pgina al inicio y al final del contenido. Permite controlar el tamao de la pgina usando las propiedades Width y Height. Tiene tambin la propiedad ContentBox que le permite establecer el rea de la pgina durante la impresin.

DocumentViewer Representa un control de visualizacin de documentos que puede hospedar contenido FixedDocument paginado como XpsDocument. En el ejemplo siguiente generamos una clase Persona con dos propiedades Nombre y Apellido. Luego una segunda clase que tiene un mtodo que devuelve un objeto List<> que devuelve varias instancias de la clase Persona. Por ltimo generamos una grilla para mostrar los datos y ponemos la grilla dentro de un documento fijo. public class Persona { public Persona() {} public Persona(string pNombre, string pApellido) { Nombre = pNombre; Apellido = pApellido; } private string _Nombre; public string Nombre { get { return _Nombre; } set { _Nombre = value; } } private string _Apellido; public string Apellido { get { return _Apellido; } set { _Apellido = value; } } } public class Personas { public List<Persona> TraerPersonas() { List<Persona> lista = new List<Persona>(); lista.Add(new Persona("Juan","Perez")); lista.Add(new Persona("Jose","Fernandez")); lista.Add(new Persona("Maria","Lopez")); lista.Add(new Persona("Pedro","Rodriguez")); return lista; } } <Window.Resources> <ObjectDataProvider x:Key="dsPersonas" ObjectType="{x:Type svc:Personas}" 102

MethodName="TraerPersonas"/> </Window.Resources> <FixedDocument> <PageContent> <FixedPage> <TextBlock Text="Listado de Personas" HorizontalAlignment="Center" FontSize="14" FontWeight="Bold"></TextBlock> <ListView Height="150" Width="280" ItemsSource="{Binding Source={StaticResource dsPersonas}}" > <ListView.View> <GridView> <GridView.Columns> <GridViewColumn Width="50" Header="Nombre" DisplayMemberBinding="{Binding Path=Nombre}"/> <GridViewColumn Width="200" Header="Apellido" DisplayMemberBinding="{Binding Path=Apellido}"/> </GridView.Columns> </GridView> </ListView.View> </ListView> </FixedPage> </PageContent> </FixedDocument>

Al igual que cualquier otro objeto puede crearse escribiendo cdigo private void Window_Loaded(object sender, RoutedEventArgs e) { FixedDocument fd = new FixedDocument(); PageContent pc = new PageContent(); FixedPage fp = new FixedPage(); ((IAddChild)pc).AddChild(fp); fd.Pages.Add(pc); Canvas cv = new Canvas(); TextBlock tb = new TextBlock(); tb.Text = "Esta es una prueba del elemento FixDocument creado por cdigo"; 103

tb.FontSize = 16; Canvas.SetLeft(tb, 10); Canvas.SetTop(tb, 10); cv.Children.Add(tb); fp.Children.Add(cv); // lo muestra en la ventana DocumentViewer dv = new DocumentViewer(); dv.Document = fd; ((IAddChild)this).AddChild(dv); }

4- Empaquetado e Impresin de Documentos


Empaquetado Las API de System.IO.Packaging proporcionan un medio eficaz de organizar los datos de la aplicacin, el contenido de los documentos y los recursos relacionados en un contenedor nico de fcil acceso, porttil y sencillo de distribuir. Un archivo ZIP es un ejemplo de un tipo de Package capaz de contener varios objetos en una sola unidad. La API de empaquetado proporciona una implementacin de ZipPackage predeterminada diseada mediante una norma basada en la especificacin Open Packaging Conventions (OPC, o Convenciones de empaquetado abierto) con arquitectura de archivo XML y ZIP. Las API de empaquetado de WPF facilitan la creacin de paquetes, as como el almacenamiento y acceso de objetos en su interior. Un objeto almacenado en un Package se denomina PackagePart (elemento). Los paquetes tambin pueden incluir certificados digitales firmados que se pueden utilizar para identificar al originador de un elemento y comprobar que no se haya modificado el contenido de un paquete. Los paquetes tambin incluyen una caracterstica PackageRelationship que permite agregar informacin adicional a un paquete o asociarla con elementos concretos sin que ello modifique el contenido de los elementos existentes. Los servicios de empaquetado tambin admiten Microsoft Windows Rights Management (RM). La arquitectura de paquetes de WPF constituye los cimientos de varias tecnologas fundamentales: Documentos XPS que cumplen XML Paper Specification (XPS). Documentos XML de formato abierto (.docx) de Microsoft Office "12". Formatos de almacenamiento personalizados para su propio diseo de aplicaciones. Basndose en las API de empaquetado, XpsDocument est diseado especficamente para almacenar documentos de contenido fijo de WPF. XpsDocument es un documento autnomo que se puede abrir en un visor, mostrar en un control DocumentViewer, enrutar a una cola de impresin o imprimir directamente en una impresora compatible con XPS.

104

Empaquetar componentes Las API de empaquetado de WPF permiten organizar los datos y documentos de la aplicacin en una sola unidad porttil. Un archivo ZIP es uno de los tipos ms comunes de paquetes y constituye el tipo de empaquetado predeterminado proporcionado con WPF. Package es una clase abstracta desde la que se implementa ZipPackage mediante una arquitectura de archivos XML de norma abierta y ZIP. De manera predeterminada, el mtodo Open utiliza ZipPackage para crear y utilizar los archivos ZIP. Un paquete puede contener tres tipos bsicos de elementos: PackagePart: Contenido de aplicaciones, datos, documentos y archivos de recursos. En un archivo ZIP, los elementos del paquete corresponden a los archivos individuales almacenados dentro del archivo ZIP. Gracias a las API de empaquetado de WPF, las aplicaciones pueden escribir, almacenar y leer varios objetos PackagePart utilizando un solo contenedor de archivos ZIP. PackageDigitalSignatures: Certificado X.509 para la identificacin, autenticacin y validacin. La firma digital no evita que se modifique un elemento, pero se produce un error en una comprobacin de la validacin en la firma digital si el elemento se ha modificado de alguna forma. La aplicacin puede emprender la accin adecuada; por ejemplo, bloquear la apertura del elemento o notificar al usuario que se ha modificado el elemento y ya no es seguro. PackageRelationships: Informacin agregada relacionada con el paquete o con un elemento concreto del mismo. Las relaciones de los paquetes proporcionan un medio reconocible de agregar y asociar informacin adicional a los elementos individuales o al paquete completo. Las relaciones de los paquetes se utilizan para dos funciones primarias, definir las relaciones de dependencia entre un elemento y otro y definir las relaciones de informacin que agregan notas u otros datos relacionados con el elemento.

Documentos XPS (XPSDocument) Un documento XML Paper Specification (XPS) es un paquete que contiene uno o ms documentos fijos junto con todos los recursos y la informacin necesarios para su representacin. XPS tambin es el formato de archivo nativo de cola de impresin de Windows Vista. XpsDocument se almacena en un conjunto de datos ZIP estndar y puede incluir una combinacin de componentes XML y binarios, tales como archivos de imagen y de fuentes. Las relaciones PackageRelationships se utilizan para definir las dependencias entre el contenido y los recursos que se necesitan para representar totalmente el documento. El diseo de XpsDocument proporciona una solucin de documento nico de alta fidelidad que admite varios usos: Lectura, escritura y almacenamiento de contenido y recursos de documentos fijos en un nico archivo porttil y fcil de distribuir. Presentacin de documentos con la aplicacin Visor de XPS. Generacin de documentos en el formato de salida de cola de impresin de Windows Vista. Enrutamiento directo de documentos a las impresoras compatibles con XPS. XpsDocumentWriter Provee mtodos para escribir en un documento XPS o en la cola de impresin. Esta clase no tiene constructor, para crearla se usa el mtodo CreateXpsDocumentWriter de la clase XpsDocument o de la clase PrintQueue. Para el siguiente ejemplo de deber agregar la referencia a System.Printing.dll using System.Windows.Xps; 105

using System.Printing; PrintDocumentImageableArea area = null; XpsDocumentWriter xdw = PrintQueue.CreateXpsDocumentWriter(ref area); if (xdw != null) xdw.Write(fd); Nota: fd es un FixedDocument creado en un ejemplo anterior Impresin de Documentos La clase PrintDialog provee otra forma de imprimir documentos usando el mtodo PrintDocument. Este mtodo enva un DocumentPaginator a una cola de impresin. La clase DocumentPaginator provee una clase abstracta que admite la creacin de elementos de varias pginas de un documento nico, o sea que soporta paginado. Un objeto DocumentPaginator puede ser obtenido desde un documento WPF, tanto fijo o dinmico. <Grid> <Grid.RowDefinitions> <RowDefinition Height="*"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <FlowDocumentReader Grid.Row="0"> <FlowDocument Name="DocPrueba" > <Paragraph>Escribiendo un prrafo en un documento dinmico para probar impresin</Paragraph> </FlowDocument> </FlowDocumentReader> <Button Grid.Row="1" Width="100" Height="23" Click="Imprimir_Click">Imprimir</Button> </Grid>

private void Imprimir_Click(object sender, RoutedEventArgs e) { PrintDialog printDialog = new PrintDialog(); if (printDialog.ShowDialog() == true) { printDialog.PrintDocument(((IDocumentPaginatorSource) DocPrueba).DocumentPaginator, "Impresin Documento Dinmico"); } }

106

Mdulo 7

Grficos, Animaciones y Multimedia

107

1- Grficos 2D
Dibujos y formas WPF proporciona objetos Drawing y Shape para representar el contenido de los dibujos grficos. Sin embargo, los objetos Drawing son estructuras ms sencillas que los objetos Shape y proporcionan mejores caractersticas de rendimiento. Shape Un objeto Shape permite dibujar una forma grfica en la pantalla. Se pueden utilizar dentro de los paneles y de la mayora de los controles. Son fciles de usar y proporcionan numerosas caractersticas tiles, tales como la administracin del diseo y el control de eventos. WPF proporciona varios objetos de forma listos para usar. Todos los objetos de formas heredan de la clase Shape. Los objetos de formas disponibles incluyen Ellipse: Borde elptico. Line: Dibuja una lnea recta entre dos puntos. Path: Dibuja una serie de lneas y curvas conectadas. Polygon: Dibuja un polgono, que es una serie de lneas conectadas que crean una forma cerrada. Polyline: Dibuja una serie de lneas rectas conectadas. Rectangle: Obtiene un rea rectangular que define los puntos inicial y final del degradado.

<Canvas> <Ellipse Canvas.Left="10" Canvas.Top="0" Height="50" Name="ellipse1" Stroke="Black" Width="100" Fill="Gray" /> <Rectangle Canvas.Left="80" Canvas.Top="20" Height="70" Name="rectangle1" Stroke="Blue" Width="150" Fill="Beige" /> <Line X1="20" Y1="20" X2="150" Y2="80" Stroke="Red" StrokeThickness="4" ></Line> <Polygon Canvas.Left="200" Canvas.Top="10" Points="50,30 60,80 40,55 30,60" Stroke="Purple" StrokeThickness="5"></Polygon> </Canvas>

Propiedades de las formas Fill: Pinta el interior. Tipo de dato Brush Stroke: Pinta el borde de la forma StrokeThickness: Establece el espesor del borde 108

Stretch: Determina como llena el espacio vaco del contenedor

Drawing Por otro lado, los objetos Drawing proporcionan una implementacin ms ligera para representar formas, imgenes y texto. Hay cuatro tipos de objetos Drawing: GeometryDrawing se utiliza para representar contenido de geometra. Los objetos de geometra se pueden utilizar para definir la regin de un control, por ejemplo, o definir la regin de recorte que se aplicar a una imagen. Los objetos de geometra pueden ser regiones simples, tales como rectngulos y crculos, o bien regiones compuestas creadas a partir de dos o ms objetos de geometra. Las regiones de geometra ms complejas se pueden crear combinando objetos derivados de PathSegment, como ArcSegment, BezierSegment y QuadraticBezierSegment. ImageDrawing dibuja una imagen. proporciona menos caractersticas que Image para representar imgenes, sin embargo, ofrece ventajas de rendimiento que lo hace ideal para describir los fondos y las imgenes prediseadas. GlyphRunDrawing dibuja texto. DrawingGroup dibuja otros dibujos. Utilice un grupo de dibujo para combinar otros dibujos en un nico dibujo compuesto. <Path Stroke="Black" StrokeThickness="1" > <Path.Data> <LineGeometry StartPoint="10,20" EndPoint="100,130" /> </Path.Data> </Path>

<Path Stroke="Black" StrokeThickness="1"> <Path.Data> <PathGeometry> <PathGeometry.Figures> <PathFigureCollection> <PathFigure StartPoint="1,10"> <PathFigure.Segments> <PathSegmentCollection> <QuadraticBezierSegment Point1="150,200" Point2="300,100" /> </PathSegmentCollection> </PathFigure.Segments> </PathFigure> </PathFigureCollection> </PathGeometry.Figures> </PathGeometry> </Path.Data> </Path> 109

Aparentemente, la clase Geometry y la clase Shape son bastante similares. Ambas se utilizan para representar grficos 2D y tienen clases concretas similares que se derivan de ellas, por ejemplo, EllipseGeometry y Ellipse. Sin embargo, existen diferencias importantes entre estos dos conjuntos de clases. En primer lugar, la clase Geometry carece de parte de la funcionalidad de la clase Shape, como la capacidad de dibujarse a s misma. Para dibujar un objeto de geometra, deber utilizarse otra clase, del tipo de DrawingContext, Drawing o Path (cabe destacar que Path es una forma) para realizar la operacin de dibujo. Las propiedades de representacin, tales como el relleno, el trazo y el grosor del trazo pertenecen a la clase que dibuja el objeto de geometra, mientras que un objeto de forma contiene estas propiedades. Podemos pensar en esta diferencia de la siguiente manera: un objeto de geometra define una regin, un crculo por ejemplo, mientras que un objeto de forma define una regin, define cmo se rellena y perfila esa regin, y participa en el sistema de diseo. Puesto que los objetos Shape se derivan de la clase FrameworkElement, utilizarlos puede aumentar significativamente el consumo de memoria de la aplicacin. Si realmente no necesita las caractersticas de FrameworkElement para el contenido grfico, es conveniente utilizar los objetos Drawing, ms ligeros. Propiedad Clip Obtiene o establece una regin que limita la regin de dibujo del grfico. <Button Content="Aceptar" Height="100" Width="100"> <Button.Clip> <EllipseGeometry Center="50,50" RadiusX="50" RadiusY="20" /> </Button.Clip> </Button>

Brush Define los objetos usados para pintar objetos grficos. Las clases que se derivan de Brush describen cmo se pinta el rea. Un objeto Brush "pinta" o "rellena" un rea con sus resultados. Los distintos pinceles tienen tipos de resultados diferentes. Algunos pinceles pintan un rea con un color slido, otros con un degradado, una trama, una imagen o un dibujo. La lista siguiente describe los distintos tipos de pinceles de WPF: SolidColorBrush: pinta un rea con un color (Color) slido. LinearGradientBrush: pinta un rea con un degradado lineal. RadialGradientBrush: pinta un rea con un degradado radial. ImageBrush: pinta un rea con una imagen (representada por un objeto ImageSource). 110

DrawingBrush: pinta un rea con un objeto Drawing. El dibujo puede incluir vectores y objetos de mapa de bits. VisualBrush: pinta un rea con un objeto Visual. VisualBrush permite duplicar el contenido de una parte de la aplicacin en otra rea; es muy til para crear efectos de reflexin y ampliar partes de la pantalla.

<StackPanel> <Rectangle Width="50" Height="20" Fill="#FF0000FF" /> <Rectangle Width="50" Height="20"> <Rectangle.Fill> <SolidColorBrush> <SolidColorBrush.Color> <!-- Usa RGB. Cada valor tiene un rango de 0-255. R red, G green, B blue. A controla transparencia --> <Color A="255" R="255" G="0" B="255" /> </SolidColorBrush.Color> </SolidColorBrush> </Rectangle.Fill> </Rectangle> <Rectangle Width="200" Height="50"> <Rectangle.Fill> <LinearGradientBrush StartPoint="0,0" EndPoint="1,1"> <GradientStop Color="Yellow" Offset="0.0" /> <GradientStop Color="Red" Offset="0.25" /> <GradientStop Color="Blue" Offset="0.75" /> <GradientStop Color="LimeGreen" Offset="1.0" /> </LinearGradientBrush> </Rectangle.Fill> </Rectangle> <Rectangle Width="200" Height="100"> <Rectangle.Fill> <RadialGradientBrush GradientOrigin="0.5,0.5" Center="0.5,0.5" RadiusX="0.5" RadiusY="0.5"> <RadialGradientBrush.GradientStops> <GradientStop Color="Yellow" Offset="0" /> <GradientStop Color="Red" Offset="0.25" /> <GradientStop Color="Blue" Offset="0.75" /> <GradientStop Color="LimeGreen" Offset="1" /> </RadialGradientBrush.GradientStops> </RadialGradientBrush> </Rectangle.Fill> </Rectangle> </StackPanel>

111

2- Imgenes
Imgenes La creacin de imgenes de WPF proporciona una mejora significativa con respecto a las funciones de creacin de imgenes de las versiones anteriores de Windows. Las funciones de creacin de imgenes, tales como la presentacin de mapas de bits o el uso de imgenes en controles comunes, se administraban principalmente por las interfases de programacin de aplicaciones (API) de la interfaz de dispositivo grfico (GDI) o GDI+ de Microsoft Windows. Estas API proporcionaban la funcionalidad bsica para la creacin de imgenes, pero carecan de caractersticas tales como compatibilidad con la extensibilidad de cdec y con imgenes de alta fidelidad. La API de creacin de imgenes de WPF se ha rediseado para superar las limitaciones de GDI y GDI+ y proporcionar un nuevo conjunto de API para mostrar y utilizar imgenes en las aplicaciones. Al utilizar imgenes, tenga en cuenta las recomendaciones siguientes para obtener el mejor rendimiento: Si su aplicacin le exige que muestre imgenes en miniatura, puede ser conveniente crear una versin de dimensiones reducidas de la imagen. De manera predeterminada, WPF carga la imagen y la decodifica a su tamao completo. Si slo desea una versin en miniatura de la imagen, WPF decodifica innecesariamente la imagen a su tamao completo y, a continuacin, la reduce a la escala en miniatura. Para evitar este consumo de recursos innecesario, puede solicitar a WPF que decodifique la imagen a un tamao en miniatura o bien solicitar a WPF que cargue una imagen en miniatura. Siempre decodifique la imagen al tamao deseado y no al tamao predeterminado. De este modo, no slo mejorar el espacio de trabajo de la aplicacin, sino tambin la velocidad de ejecucin. Si es posible, combine las imgenes en una imagen nica, como una tira cinematogrfica creada de varias imgenes. Se utiliza un cdec para descodificar o codificar cada formato multimedia concreto. Las imgenes WPF incluyen un cdec para los formatos de imagen BMP, JPEG, PNG, TIFF, Windows Media Photo, GIF y de icono. Cada uno de estos cdecs permite a las aplicaciones decodificar y, con la excepcin de los iconos, codificar sus formatos de imagen respectivos. La seleccin del cdec es automtica a menos que se especifique un descodificador concreto.

Control Image Hay varias maneras de mostrar una imagen en una aplicacin de Windows Presentation Foundation (WPF). Las imgenes se pueden mostrar mediante un control Image, pintado en un objeto visual con un objeto ImageBrush, o dibujado con un objeto ImageDrawing. Image es un elemento de marco de trabajo y la manera principal de mostrar imgenes en aplicaciones. En muchos casos se utiliza un objeto BitmapImage para hacer referencia a un archivo de imagen. BitmapImage es un BitmapSource especializado que se optimiza para la carga en Lenguaje de marcado de aplicaciones extensible (XAML) y constituye una manera fcil de mostrar imgenes como la propiedad Source de un control Image. El uso de las propiedades DecodePixelWidth o DecodePixelHeight ahorra memoria de la aplicacin. <StackPanel> <Image Width="150" Source="mslogo.jpg"/> <Image Width="130"> <Image.Source> <BitmapImage DecodePixelWidth="130" UriSource="mslogo.jpg" /> </Image.Source> </Image> </StackPanel> 112

Girar, Convertir y Recortar Imgenes WPF permite a los usuarios transformar imgenes utilizando las propiedades de BitmapImage o mediante objetos BitmapSource adicionales, tales como CroppedBitmap o FormatConvertedBitmap. Estas transformaciones de imagen pueden girar una imagen, ajustar su escala, cambiar su formato de pxel o recortarla. Los giros de imagen se realizan mediante la propiedad Rotation de BitmapImage. Los giros slo se pueden hacer en incrementos de 90 grados. En el siguiente ejemplo vemos como rotar la imagen 90 <Image Height ="150"> <Image.Source> <TransformedBitmap Source="mslogo.jpg" > <TransformedBitmap.Transform> <RotateTransform Angle="90"/> </TransformedBitmap.Transform> </TransformedBitmap> </Image.Source> </Image>

En este ejemplo convertimos la imagen a tonos de gris. <Image Width="150" > <Image.Source> <FormatConvertedBitmap Source="mslogo.jpg" DestinationFormat="Gray2" /> </Image.Source> </Image>

113

En este ejemplo recortamos la imagen. <Image Width="200" Source="mslogo.jpg"> <Image.Clip> <EllipseGeometry Center="75,10" RadiusX="40" RadiusY="15" /> </Image.Clip> </Image>

Expandir imgenes La propiedad Stretch controla cmo se expande una imagen para rellenar su contenedor. La propiedad Stretch acepta los valores siguientes, definidos por la enumeracin Stretch: None: la imagen no se expande para rellenar el rea de salida. Si la imagen es mayor que el rea de salida, la imagen se dibuja en el rea de salida, y se recorta lo que sobra. Fill: se ajusta la escala de la imagen al rea de salida. Dado que la escala se aplica de manera independiente al alto y al ancho de la imagen, puede que no se conserve su relacin de aspecto original. Es decir, es posible que la imagen se distorsione para rellenar totalmente el contenedor de salida. Uniform: se cambia la escala de la imagen de modo que se ajuste completamente al rea de salida. Se conserva la relacin de aspecto de la imagen. UniformToFill: la escala de la imagen se ajusta hasta rellenar completamente el rea de salida y se conserva la relacin de aspecto original de la imagen.

<Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="100"/> <ColumnDefinition Width="100"/> <ColumnDefinition Width="100"/> <ColumnDefinition Width="100"/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="50"/> </Grid.RowDefinitions> <Image Grid.Row="0" Grid.Column="0" Source="mslogo.jpg" Stretch="None" /> <Image Grid.Row="0" Grid.Column="1" Source="mslogo.jpg" Stretch="Fill" /> <Image Grid.Row="0" Grid.Column="2" Source="mslogo.jpg" Stretch="Uniform" /> <Image Grid.Row="0" Grid.Column="3" Source="mslogo.jpg" Stretch="UniformToFill" /> </Grid>

114

Pintar con imgenes Las imgenes tambin se pueden mostrar en una aplicacin pintndolas con un objeto Brush. Los pinceles permiten pintar los objetos de una interfase de usuario con cualquier cosa desde simples colores slidos hasta conjuntos complejos de tramas e imgenes. Para pintar con imgenes, utilice un ImageBrush. Un ImageBrush es un tipo de TileBrush que define su contenido como una imagen de mapa de bits. Un ImageBrush muestra una imagen nica, que se especifica mediante su propiedad ImageSource. Puede controlar cmo se expande, alinea o coloca en mosaico la imagen, a fin de evitar la distorsin y crear tramas y otros efectos. <Button Height="50" Width="100" Foreground="White" FontWeight="Bold" FontSize="14" > Aceptar <Button.Background> <ImageBrush ImageSource="Flower2.jpg" /> </Button.Background> </Button>

3- Grficos 3D
La implementacin de 3D en WPF permite a los programadores dibujar, transformar y animar grficos 3D en el marcado y en el cdigo de procedimientos, utilizando las mismas funciones permitidas por la plataforma a los grficos 2D. Los programadores pueden combinar grficos 2D y 3D para crear controles enriquecidos, proporcionar ilustraciones complejas de datos o mejorar la experiencia del usuario con la interfaz de una aplicacin. La compatibilidad con 3D de WPF no est diseada para proporcionar una plataforma con todas las funciones para la programacin de juegos.

Viewport3D El contenido de los grficos 3D de WPF se encapsula en un elemento, Viewport3D, que puede participar en la estructura de elementos bidimensionales. El sistema de grficos trata Viewport3D como un elemento visual bidimensional como tantos en WPF. Viewport3D acta como una ventana, un rea de visualizacin, a una escena tridimensional. Expresado de modo ms preciso, es la superficie sobre la que se proyecta una escena 3D. En una aplicacin 2D convencional, utilice Viewport3D como cualquier otro elemento contenedor, como Grid o Canvas. Aunque puede utilizar Viewport3D con otros objetos de dibujo 2D en el mismo grfico de escena, no puede combinar objetos 2D y 3D dentro de Viewport3D.

115

Espacio de coordenadas 3D El sistema de coordenadas de WPF para grficos 2D localiza el origen en la parte superior izquierda del rea de representacin (que suele ser la pantalla). En el sistema 2D, los valores positivos del eje X se extienden hacia la derecha, y los valores positivos del eje Y extienden hacia abajo. En el sistema de coordenadas 3D, sin embargo, el origen se encuentra en el centro del rea de representacin, los valores positivos del eje X se extienden hacia la derecha, los valores positivos del eje Y se extienden hacia arriba (no hacia abajo) y los valores positivos del eje Z se extienden hacia el exterior partiendo del origen, es decir, hacia el espectador.

Cmaras y proyecciones Los programadores que trabajan en 2D estn acostumbrados a colocar los elementos de dibujo primitivos en una pantalla bidimensional. Al crear una escena 3D, es importante recordar que, en realidad, se est creando una representacin 2D de los objetos 3D. Dado que una escena 3D tiene un aspecto diferente dependiendo del punto de vista del espectador, debe especificar ese punto de vista. La clase Camera permite especificar este punto de vista para una escena 3D. Otra manera de entender cmo se representa una escena 3D en una superficie 2D consiste en describir dicha escena como una proyeccin sobre la superficie de visualizacin. ProjectionCamera permite especificar proyecciones diferentes y sus propiedades para cambiar la manera en que el espectador ve los modelos 3D. PerspectiveCamera proporciona una perspectiva de punto de fuga. Puede especificar la posicin de la cmara en el espacio de coordenadas de la escena, la direccin y el campo de visin de la cmara, y un vector que define la direccin "hacia arriba" en la escena. Las propiedades NearPlaneDistance y FarPlaneDistance de ProjectionCamera limitan el intervalo de proyeccin de la cmara. Dado que las cmaras se pueden ubicar en cualquier parte de la escena, es posible situarlas dentro de un modelo o muy cerca de l, con lo que resultara difcil distinguir correctamente los objetos. NearPlaneDistance permite especificar una distancia mnima a la cmara a partir de la cual no se dibujarn objetos. A la inversa, FarPlaneDistance permite especificar una distancia mxima a la cmara, ms all de la que no se dibujarn objetos, lo que garantice que no se incluyan en la escena aquellos objetos que estn demasiado lejos para ser reconocibles. OrthographicCamera especifica una proyeccin ortogonal de un modelo 3D sobre una superficie visual 2D. Al igual que otras cmaras, especifica una posicin, direccin de visualizacin y direccin "hacia arriba". OrthographicCamera describe un cuadro de vista cuyos lados son paralelos, en lugar de uno cuyos lados convergen en un punto de la cmara.

116

Elementos primitivos de modelo y malla Model3D es la clase base abstracta que representa un objeto 3D genrico. Para generar una escena 3D, necesita algunos objetos que ver; los objetos que componen el grfico de escena se derivan de la clase Model3D. En la actualidad, WPF permite geometras de modelado con GeometryModel3D. Para crear un modelo, comience por crear un elemento primitivo, o malla. Un elemento 3D primitivo es una coleccin de vrtices que constituyen una entidad 3D nica. La mayora de los sistemas 3D proporcionan elementos primitivos modelados a partir de la figura cerrada ms simple: un tringulo definido por tres vrtices. Dado que los tres puntos de un tringulo son coplanares, puede seguir agregando tringulos para modelar formas ms complejas, denominadas mallas. El sistema 3D de WPF proporciona actualmente la clase MeshGeometry3D, que permite especificar cualquier geometra; en este momento, no admite elementos 3D primitivos predefinidos, tales como esferas o formas cbicas. Empiece por crear MeshGeometry3D especificando una lista de vrtices de tringulos como su propiedad Positions. Cada vrtice se especifica como un Point3D. (En Lenguaje de marcado de aplicaciones extensible (XAML), especifique esta propiedad como una lista de nmeros agrupados en ternas, que representan las coordenadas de cada vrtice.) Segn cul sea la geometra, la malla puede estar compuesta de muchos tringulos, algunos de los cuales compartirn las mismas esquinas (vrtices). WPF necesita informacin sobre qu tringulos comparten qu vrtices para dibujar la malla correctamente. Esta informacin se proporciona especificando una lista de ndices de tringulos con la propiedad TriangleIndices. Esta lista especifica el orden en el que los puntos especificados en la lista Positions determinarn un tringulo. Puede seguir definiendo el modelo especificando valores para las propiedades Normals y TextureCoordinates. Para representar la superficie del modelo, el sistema de grficos necesita informacin sobre en qu direccin mira la superficie de cualquier tringulo dado. Utiliza esta informacin para realizar los clculos de iluminacin del modelo: las superficies que miran directamente hacia una fuente de luz parecen ms luminosas que las que tienen un ngulo que las oculta de la luz. Aunque WPF puede determinar los vectores normales predeterminados utilizando las coordenadas de posicin, tambin es posible especificar vectores normales diferentes para crear un aspecto ms aproximado de las superficies curvas.

La propiedad TextureCoordinates especifica una coleccin de puntos (Point) que indica al sistema de grficos cmo asignar las coordenadas que determinan cmo trazar una textura en los vrtices de la malla. Las TextureCoordinates se especifican como un valor comprendido entre cero y 1, incluidos. Como sucede con la propiedad Normals, el sistema de grficos puede calcular las coordenadas de textura predeterminadas, pero si lo desea puede establecer coordenadas de textura diferentes a fin de controlar la asignacin de una textura que incluya parte de un patrn repetitivo. 117

Materiales del Modelo Para que una malla parezca un objeto tridimensional, debe tener una textura aplicada que cubra la superficie definida por sus vrtices y tringulos, de manera que se pueda iluminar y proyectar por la cmara. En 2D, se utiliza la clase Brush para aplicar colores, patrones, degradados y otro contenido visual a las reas de la pantalla. El aspecto de los objetos 3D, sin embargo, depende del modelo de iluminacin, no slo del color o del patrn que se les aplica. Los objetos reales reflejan la luz de manera distinta segn la calidad de su superficie: las superficies satinadas y brillantes no tienen el mismo aspecto que las superficies speras o mates, y algunos objetos parecen absorber la luz, mientras que otros la emiten. Puede aplicar a los objetos 3D los mismos pinceles que a los objetos 2D, pero no directamente. Para definir las caractersticas de la superficie de un modelo, WPF utiliza la clase abstracta Material. Las subclases concretas de Material determinan algunas de las caractersticas del aspecto de la superficie del modelo y, adems, cada una de ellas proporciona una propiedad Brush a la que puede pasar SolidColorBrush, TileBrush o VisualBrush. DiffuseMaterial especifica que el pincel se aplicar al modelo como si estuviera iluminado con una luz difusa. Utilizar DiffuseMaterial es lo que ms se parece al uso directo de pinceles en los modelos 2D; las superficies del modelo no reflejan la luz como si brillasen. SpecularMaterial especifica que el pincel se aplicar al modelo como si la superficie del modelo fuese dura o brillante, capaz de reflejar la iluminacin. Puede establecer el grado en que la textura sugerir esta cualidad de reflexin, o "brillo", especificando un valor para la propiedad SpecularPower. EmissiveMaterial permite especificar que la textura se aplicar como si el modelo estuviera emitiendo luz del mismo color que el pincel. Esto no convierte el modelo en una luz; sin embargo, participar de manera diferente en el sombreado que si se aplica textura con DiffuseMaterial o SpecularMaterial. Para mejorar rendimiento, las caras ocultas de GeometryModel3D (aqullas que estn fuera de la vista porque se encuentran en el lado del modelo opuesto a la cmara) se seleccionan de la escena. Para especificar el Material que se aplicar a la cara oculta de un modelo, como un plano, establezca la propiedad BackMaterial del modelo. Para lograr algunas cualidades de la superficie, como el brillo o los efectos de reflejo, puede ser conveniente aplicar sucesivamente varios pinceles diferentes a un modelo. Puede aplicar y reutilizar varios materiales mediante la clase MaterialGroup. Los elementos secundarios de MaterialGroup se aplican del primero al ltimo en varias pasadas de representacin.

Iluminar la escena Las luces de los grficos 3D hacen lo mismo que las luces en el mundo real: permiten ver las superficies. Ms concretamente, las luces determinan qu parte de una escena se incluye en la proyeccin. Los objetos de luz en WPF crean gran variedad de efectos de luz y sombra y siguen el modelo de comportamiento de diversas luces del mundo real. Debe incluir por lo menos una luz en la escena, pues de lo contrario no habr ningn modelo visible. Las luces siguientes se derivan de la clase base Light: AmbientLight: proporciona iluminacin de ambiente que ilumina uniformemente todos los objetos sin tener en cuenta su ubicacin u orientacin. DirectionalLight: ilumina como una fuente de luz distante. Las luces direccionales tienen Direction, que se especifica como Vector3D, pero ninguna ubicacin concreta. PointLight: ilumina como una fuente de luz cercana. Las luces puntuales tienen posicin y emiten la luz desde esa posicin. Los objetos de la escena se iluminan dependiendo de su posicin y distancia con respecto a la luz. PointLightBase expone una propiedad Range, que determina una distancia ms all de la cual la luz no iluminar los modelos. PointLight tambin expone propiedades de atenuacin que 118

determinan cmo disminuye la intensidad de la luz con la distancia. Puede especificar interpolaciones constantes, lineales o cuadrticas para la atenuacin de la luz. SpotLight: hereda de PointLight. Los focos de luz iluminan como las luces puntuales, y tienen posicin y direccin. Proyectan la luz en un rea cnica establecida por las propiedades InnerConeAngle y OuterConeAngle, especificada en grados. Las luces son objetos Model3D, por lo que puede transformar y animar las propiedades de la luz, incluidas su posicin, posicin, color, direccin y alcance.

El siguiente ejemplo arma un grfico 3D aplicando los objetos vistos <Canvas Width="200" Height="201"> <!-- Viewport3D provee la superficie --> <Viewport3D ClipToBounds="True" Width="150" Height="150" Canvas.Left="0" Canvas.Top="10"> <!-- Define la cmara --> <Viewport3D.Camera> <PerspectiveCamera Position="0,0,2" LookDirection="0,0,-1" FieldOfView="60" /> </Viewport3D.Camera> <Viewport3D.Children> <!-- ModelVisual3D define la luz de la escena. sin luz los objetos 3D no pueden verse. La direccin de la luz define las sombras. Se pueden crear mltiples luces con diferentes colores que brillen en distintas direcciones --> <ModelVisual3D> <ModelVisual3D.Content> <DirectionalLight Color="#FFFFFF" Direction="-0.612372,-0.5,-0.612372" /> </ModelVisual3D.Content> </ModelVisual3D> <ModelVisual3D> <ModelVisual3D.Content> <GeometryModel3D> <!-- La geometra especifica la forma del plano 3D. --> <GeometryModel3D.Geometry> <MeshGeometry3D TriangleIndices="0,1,2 3,4,5 " Normals="0,0,1 0,0,1 0,0,1 0,0,1 0,0,1 0,0,1 " TextureCoordinates="0,0 1,0 1,1 1,1 0,1 0,0 " Positions="-0.5,-0.5,0.5 0.5,-0.5,0.5 0.5,0.5,0.5 0.5,0.5,0.5 -0.5,0.5,0.5 0.5,-0.5,0.5 " /> </GeometryModel3D.Geometry> <!-- El material especifica el material aplicado al objeto 3D. --> <GeometryModel3D.Material> <MaterialGroup> <DiffuseMaterial> <DiffuseMaterial.Brush> <LinearGradientBrush StartPoint="0,0.5" EndPoint="1,0.5"> <LinearGradientBrush.GradientStops> <GradientStop Color="Yellow" Offset="0" /> <GradientStop Color="Red" Offset="0.25" /> <GradientStop Color="Blue" Offset="0.75" /> <GradientStop Color="LimeGreen" Offset="1" /> </LinearGradientBrush.GradientStops> </LinearGradientBrush> </DiffuseMaterial.Brush> </DiffuseMaterial> 119

</MaterialGroup> </GeometryModel3D.Material> <!-- Se puede aplicar transformaciones al objeto. --> <GeometryModel3D.Transform> <RotateTransform3D> <RotateTransform3D.Rotation> <AxisAngleRotation3D Axis="0,3,0" Angle="40" /> </RotateTransform3D.Rotation> </RotateTransform3D> </GeometryModel3D.Transform> </GeometryModel3D> </ModelVisual3D.Content> </ModelVisual3D> </Viewport3D.Children> </Viewport3D> </Canvas>

Transformar modelos Al crear modelos, stos tienen una ubicacin determinada en la escena. Para mover esos modelos por la escena, girarlos o cambiar su tamao, no es prctico cambiar los vrtices que definen los propios modelos. En lugar de ello, al igual que en 2D, se aplican transformaciones a los modelos. Cada objeto de modelo tiene una propiedad Transform con la que puede mover, reorientar o cambiar el tamao del modelo. Al aplicar una transformacin, en realidad lo que se hace es desplazar todos los puntos del modelo segn un vector o valor especificado por la transformacin. En otras palabras, se transforma el espacio de coordenadas en el que se ha definido el modelo ("espacio del modelo"), pero no se cambian los valores que constituyen la geometra del modelo en el sistema de coordenadas de la escena completa ("espacio universal").

Animar modelos La implementacin de 3D en WPF utiliza el mismo sistema de control de tiempo y animacin que los grficos 2D. En otras palabras, para animar una escena 3D, se animan las propiedades de sus modelos. Es posible animar directamente las propiedades de los elementos primitivos, pero suele ser ms fcil de animar las transformaciones que cambian la posicin o el aspecto 120

de los modelos. Dado que las transformaciones se pueden aplicar a los objetos Model3DGroup as como a los modelos individuales, es posible aplicar un conjunto de animaciones a un elemento secundario de Model3DGroup y otro conjunto de animaciones a un grupo de objetos secundarios. Tambin puede lograr gran variedad de efectos visuales animando las propiedades de iluminacin de la escena. Finalmente, si lo desea puede animar la propia proyeccin, animando la posicin de la cmara o el campo de visin. Para animar un objeto en WPF, se crea una escala de tiempo, se define una animacin (que, en realidad, es un cambio de algn valor de propiedad a lo largo del tiempo) y se especifica la propiedad a la que aplicar la animacin. Dado que todos los objetos de una escena 3D son elementos secundarios de Viewport3D, las propiedades de destino de cualquier animacin que desea aplicar a la escena son propiedades de propiedades de Viewport3D. La clase Storyboard controla las animaciones con una escala de tiempo y proporciona informacin de destino de objetos y propiedades para sus animaciones secundarias. Un objeto Storyboard puede considerarse como un contenedor de otros objetos de animacin (por ejemplo, DoubleAnimation) y de otros objetos Storyboard. Es decir, se pueden anidar objetos Storyboard unos dentro de otros y especificar valores de BeginTime para cada Storyboard por separado. El uso de guiones grficos anidados puede ayudarle a orquestar secuencias de animacin detalladas. Cada Storyboard secundario esperar hasta que comience su Storyboard primario y, a continuacin, iniciar la cuenta atrs antes de que comience a su vez. La Clase DoubleAnimation anima el valor de una propiedad Double entre dos valores de destino usando la interpolacin lineal en una propiedad Duration especificada. Una animacin actualiza el valor de una propiedad durante un perodo de tiempo. Un efecto de animacin puede ser sutil, como mover un Shape unos cuantos pxeles a la izquierda o a la derecha, o espectacular, como ampliar el tamao original de un objeto 200 veces mientras gira y cambia de color. Para crear una animacin, se asocia una animacin al valor de propiedad de un objeto. La clase DoubleAnimation crea una transicin entre dos valores de destino. Para establecer sus valores de destino, use sus propiedades From, To y By. La animacin progresa desde el valor From hasta el valor especificado por la propiedad To. By permite sumar valores.

Transformaciones de Traslacin Las transformaciones 3D heredan de la clase base abstracta Transform3D; se incluyen las clases de transformaciones afines TranslateTransform3D, ScaleTransform3D y RotateTransform3D. El sistema 3D de Windows Presentation Foundation (WPF) tambin proporciona una clase MatrixTransform3D que permite especificar las mismas transformaciones en operaciones de matrices ms precisas. TranslateTransform3D translada objetos en un plazo tridimensional (x-y-z). El siguiente ejemplo genera que el rectngulo se mueva a derecha e izquierda. <Canvas Width="300" Height="201"> <Viewport3D Name="MyAnimatedObject" ClipToBounds="True" Width="300" Height="150" Canvas.Left="0" Canvas.Top="10"> <Viewport3D.Camera> <PerspectiveCamera x:Name="myPerspectiveCamera" Position="0,0,2" LookDirection="0,0,-1" FieldOfView="60" /> </Viewport3D.Camera> <Viewport3D.Children> <ModelVisual3D> <ModelVisual3D.Content> <DirectionalLight Color="#FFFFFF" Direction="-0.612372,-0.5,-0.612372" /> </ModelVisual3D.Content> 121

</ModelVisual3D> <ModelVisual3D> <ModelVisual3D.Content> <GeometryModel3D> <GeometryModel3D.Geometry> <MeshGeometry3D TriangleIndices="0,1,2 3,4,5 " Normals="0,0,1 0,0,1 0,0,1 0,0,1 0,0,1 0,0,1 " TextureCoordinates="0,0 1,0 1,1 1,1 0,1 0,0 " Positions="-0.5,-0.5,0.5 0.5,-0.5,0.5 0.5,0.5,0.5 0.5,0.5,0.5 -0.5,0.5,0.5 -0.5,-0.5,0.5 " /> </GeometryModel3D.Geometry> <GeometryModel3D.Material> <MaterialGroup> <DiffuseMaterial> <DiffuseMaterial.Brush> <SolidColorBrush Color="Cyan" Opacity="0.3"/> </DiffuseMaterial.Brush> </DiffuseMaterial> </MaterialGroup> </GeometryModel3D.Material> <!-- La propiedad OffsetX esta animada por el Storyboard de abajo. --> <GeometryModel3D.Transform> <TranslateTransform3D x:Name="myTranslateTransform3D" OffsetX="0" OffsetY="0" OffsetZ="0" /> </GeometryModel3D.Transform> </GeometryModel3D> </ModelVisual3D.Content> </ModelVisual3D> </Viewport3D.Children> <!-- Dispara la transformacin de traslacin --> <Viewport3D.Triggers> <EventTrigger RoutedEvent="Viewport3D.Loaded"> <BeginStoryboard> <Storyboard> <DoubleAnimation Storyboard.TargetName="myTranslateTransform3D" Storyboard.TargetProperty="OffsetX" To="-0.8" AutoReverse="True" RepeatBehavior="Forever" /> <!-- Si se desea animar OffsetY y/o OffsetZ crear un cdigo similar--> </Storyboard> </BeginStoryboard> </EventTrigger> </Viewport3D.Triggers> </Viewport3D> </Canvas>

122

Transformaciones de Escala ScaleTransform3D cambia la escala del modelo mediante un vector de escala especificado respecto a un punto central. Especifique una escala uniforme, que escala el modelo mediante el mismo valor en los ejes X, Y y Z, para cambiar proporcionalmente el tamao del modelo. Por ejemplo, si se establece el valor de las propiedades ScaleX, ScaleY y ScaleZ de la transformacin en mitades de 0,5 del tamao del modelo; al establecer el valor de las mismas propiedades en 2 se duplica su escala en los tres ejes.

Si se especifica una transformacin de escala no uniforme (una transformacin de escala cuyos valores X, Y y Z no son iguales), se puede provocar el estiramiento o la contraccin del modelo en una o dos dimensiones sin afectar el resto. Por ejemplo, si se establece el valor de ScaleX en 1, de ScaleY en 2 y de ScaleZ en 1, se provocara la duplicacin del alto del modelo transformado pero los ejes X y Z permaneceran iguales. De forma predeterminada, ScaleTransform3D provoca la expansin o contraccin de los vrtices en el origen (0,0,0). Si el modelo que desea transformar no se dibuja partiendo del origen, sin embargo, al escalar el modelo a partir del origen, no se escalar el modelo "en contexto". En su lugar, cuando se multiplican los vrtices del modelo por el vector de escala, la operacin de la escala tendr el efecto de trasladar y escalar el modelo.

123

Para escalar un modelo "en contexto", especifique el centro del mismo estableciendo el valor de las propiedades CenterX, CenterY y CenterZ de ScaleTransform3D. De esta forma, se asegura de que el sistema de grficos escala el espacio del modelo y, a continuacin, lo traslada para centrarse en el objeto Point3Despecificado. A la inversa, si ha generado el modelo en el origen y ha especificado un punto central diferente, espere ver el modelo trasladado fuera del origen. Para ver la transformacin de escala prueba el cdigo siguiente con y la parte de cdigo en negrita y observe la transformacin. <Canvas Width="321" Height="201"> <Viewport3D ClipToBounds="True" Width="150" Height="150" Canvas.Left="0" Canvas.Top="10"> <Viewport3D.Camera> <PerspectiveCamera Position="0,0,2" LookDirection="0,0,-1" FieldOfView="60" /> </Viewport3D.Camera> <Viewport3D.Children> <ModelVisual3D> <ModelVisual3D.Content> <DirectionalLight Color="#FFFFFF" Direction="-0.612372,-0.5,-0.612372" /> </ModelVisual3D.Content> </ModelVisual3D> <ModelVisual3D> <ModelVisual3D.Content> <GeometryModel3D> <GeometryModel3D.Geometry> <MeshGeometry3D TriangleIndices="0,1,2 3,4,5 " Normals="0,0,1 0,0,1 0,0,1 0,0,1 0,0,1 0,0,1 " TextureCoordinates="0,0 1,0 1,1 1,1 0,1 0,0 " Positions="-0.5,-0.5,0.5 0.5,-0.5,0.5 0.5,0.5,0.5 0.5,0.5,0.5 -0.5,0.5,0.5 -0.5,-0.5,0.5 " /> </GeometryModel3D.Geometry> <GeometryModel3D.Material> <MaterialGroup> <DiffuseMaterial> <DiffuseMaterial.Brush> <LinearGradientBrush StartPoint="0,0.5" EndPoint="1,0.5"> <LinearGradientBrush.GradientStops> <GradientStop Color="Yellow" Offset="0" /> <GradientStop Color="Red" Offset="0.25" /> <GradientStop Color="Blue" Offset="0.75" /> <GradientStop Color="LimeGreen" Offset="1" /> </LinearGradientBrush.GradientStops> </LinearGradientBrush> </DiffuseMaterial.Brush> </DiffuseMaterial> </MaterialGroup> </GeometryModel3D.Material> <GeometryModel3D.Transform> <ScaleTransform3D ScaleX="2" ScaleY="0.2" ScaleZ="1" CenterX="0" CenterY="0" CenterZ="0" /> </GeometryModel3D.Transform> </GeometryModel3D> 124

</ModelVisual3D.Content> </ModelVisual3D> </Viewport3D.Children> </Viewport3D> </Canvas>

Transformaciones de Giro Puede girar un modelo 3D de varias maneras diferentes. Una transformacin de giro tpica especifica un eje y un ngulo de giro alrededor de ese eje. La clase RotateTransform3D permite definir un objeto Rotation3D con su propiedad Rotation. Despus especifique las propiedades Axis y Angle en Rotation3D, en este caso un objeto AxisAngleRotation3D, para definir la transformacin. El siguiente ejemplo genera la rotacin de la figura. <Canvas Width="321" Height="201"> <Viewport3D Name="MyAnimatedObject" ClipToBounds="True" Width="150" Height="150" Canvas.Left="0" Canvas.Top="10"> <Viewport3D.Camera> <PerspectiveCamera x:Name="myPerspectiveCamera" Position="0,0,2" LookDirection="0,0,-1" FieldOfView="60" /> </Viewport3D.Camera> <Viewport3D.Children> <ModelVisual3D> <ModelVisual3D.Content> <DirectionalLight Color="#FFFFFF" Direction="-0.612372,-0.5,-0.612372" /> </ModelVisual3D.Content> </ModelVisual3D> <ModelVisual3D> <ModelVisual3D.Content> <DirectionalLight Color="#FFFFFF" Direction="0.612372,-0.5,-0.612372" /> </ModelVisual3D.Content> </ModelVisual3D> <ModelVisual3D> <ModelVisual3D.Content> <GeometryModel3D> <GeometryModel3D.Geometry> 125

<MeshGeometry3D TriangleIndices="0,1,2 3,4,5 " Normals="0,0,1 0,0,1 0,0,1 0,0,1 0,0,1 0,0,1 " TextureCoordinates="0,0 1,0 1,1 1,1 0,1 0,0 " Positions="-0.5,-0.5,0.5 0.5,-0.5,0.5 0.5,0.5,0.5 0.5,0.5,0.5 -0.5,0.5,0.5 -0.5,-0.5,0.5 " /> </GeometryModel3D.Geometry> <GeometryModel3D.Material> <MaterialGroup> <DiffuseMaterial> <DiffuseMaterial.Brush> <LinearGradientBrush StartPoint="0,0.5" EndPoint="1,0.5"> <LinearGradientBrush.GradientStops> <GradientStop Color="Yellow" Offset="0" /> <GradientStop Color="Red" Offset="0.25" /> <GradientStop Color="Blue" Offset="0.75" /> <GradientStop Color="LimeGreen" Offset="1" /> </LinearGradientBrush.GradientStops> </LinearGradientBrush> </DiffuseMaterial.Brush> </DiffuseMaterial> </MaterialGroup> </GeometryModel3D.Material> <!-- La propiedad Rotation del objeto esta animada para causar la rotacin del mismo --> <GeometryModel3D.Transform> <RotateTransform3D> <RotateTransform3D.Rotation> <AxisAngleRotation3D x:Name="myAngleRotation" Axis="0,3,0" Angle="40" /> </RotateTransform3D.Rotation> </RotateTransform3D> </GeometryModel3D.Transform> </GeometryModel3D> </ModelVisual3D.Content> </ModelVisual3D> </Viewport3D.Children> <!-- Dispara la animacin de rotacin--> <Viewport3D.Triggers> <EventTrigger RoutedEvent="Viewport3D.Loaded"> <BeginStoryboard> <Storyboard> <!-- Esta animacin anima la propiedad Angle de AxisAngleRotation3D haciendo que el objeto rote de -60 a 60 --> <DoubleAnimation Storyboard.TargetName="myAngleRotation" Storyboard.TargetProperty="Angle" From="-60" To="60" Duration="0:0:4" AutoReverse="True" RepeatBehavior="Forever"/> <!-- Esta animacin anima la propiedad Axis de AxisAngleRotation3D haciendo que el objeto se tambalee mientras rota --> <Vector3DAnimation 126

Storyboard.TargetName="myAngleRotation" Storyboard.TargetProperty="Axis" From="0,3,0" To="1,0,1" Duration="0:0:4" AutoReverse="True" RepeatBehavior="Forever"/> </Storyboard> </BeginStoryboard> </EventTrigger> </Viewport3D.Triggers> </Viewport3D> </Canvas>

4- Multimedia
Multimedia permite a Windows Presentation Foundation (WPF) integrar Audio y Video a las aplicaciones. Media API Las clases MediaElement y MediaPlayer se usan para presentar Audio y Video. Estas clases pueden ser controladas interactivamente o por reloj. Se pueden usar con el control Microsoft Windows Media Player 10. MediaElement es un elemento que puede ser utilizado como contenido de varios controles. Puede usarse desde XAML o por cdigo. MediaPlayer, en cambio, est diseado para objetos Drawing. Solo puede ser presentado usando VideoDrawing o directamente interactuando con DrawingContext. No puede usarse en XAML. <StackPanel Margin="20"> <MediaElement Source="media/numbers-aud.wmv" /> </StackPanel> MediaPlayer player = new MediaPlayer(); player.Open(new Uri(@"sampleMedia\xbox.wmv", UriKind.Relative)); VideoDrawing aVideoDrawing = new VideoDrawing(); aVideoDrawing.Rect = new Rect(0, 0, 100, 100); aVideoDrawing.Player = player; player.Play(); Modos Media Playback Controla los diferentes modos que un medio puede ser reproducido. Tanto MediaElement como MediaPlayer pueden usar ambos modos. Si Clock est en nulo el medio se reproduce en forma independiente. 127

Modo Independiente: Predeterminado. Se puede especificar la URI del medio, controlar su reproduccin, etc. Permite usar los mtodos Play, Pause, Close y Stop. Modo Reloj: La reproduccin se controla con MediaTimeline. Los mtodos Play, Pause, Close y Stop est inhabilitados. <MediaElement Name="myMediaElement" > <MediaElement.Triggers> <EventTrigger RoutedEvent="MediaElement.Loaded"> <EventTrigger.Actions> <BeginStoryboard> <Storyboard> <!-- La MediaTimeline tiene RepeatBehavior="Forever" que genera que se repita eternamente--> <MediaTimeline Source="media\tada.wav" Storyboard.TargetName="myMediaElement" RepeatBehavior="Forever" /> </Storyboard> </BeginStoryboard> </EventTrigger.Actions> </EventTrigger> </MediaElement.Triggers> </MediaElement>

SoundPlayer Controla la reproduccin del sonido de un archivo .wav. Proporciona una interfaz simple para cargar y reproducir un archivo .wav. Permite cargar un archivo .wav desde una ruta de acceso de archivo, una direccin URL, un Stream que contiene un archivo .wav o un recurso incrustado que contiene un archivo .wav. Para reproducir un sonido mediante la clase SoundPlayer, configure un SoundPlayer con una ruta de acceso al archivo .wav y llame a uno de los mtodos de reproduccin. Para identificar el archivo .wav que desee reproducir, utilice uno de los constructores o establezca el valor de la propiedad SoundLocation o Stream. El archivo se puede cargar antes de reproducirlo utilizando uno de los mtodos de carga, o bien, se puede diferir la carga hasta que se llame a uno de los mtodos de reproduccin. El objeto SoundPlayer configurado para cargar un archivo .wav desde una Stream o una direccin URL debe cargar el archivo en la memoria antes de que comience la reproduccin. private void Window_Loaded(object sender, RoutedEventArgs e) { System.Media.SoundPlayer sp = new System.Media.SoundPlayer(); sp.SoundLocation = txtArchivo.Text; sp.Play(); }

128

Mdulo 8

Configuracin y Distribucin

129

1- Configuracin
Configurar Aplicaciones La configuracin de la aplicacin le permite almacenar y recuperar dinmicamente la configuracin de propiedades y cualquier otra informacin de la aplicacin, as como mantener las preferencias de usuario y de la aplicacin personalizada en el equipo cliente. Con frecuencia son datos necesarios, como una cadena de conexin, para ejecutar la aplicacin que no desea incluir directamente en el cdigo. Quiz desee almacenar dos cadenas de conexin a bases de datos diferentes y recuperar una de ellas en funcin de la ubicacin del equipo en tiempo de ejecucin. O bien, puede almacenar las preferencias de color de un usuario y, a continuacin, recuperarlas la siguiente vez que ejecute la aplicacin. Cada configuracin debe tener un nombre nico; el nombre puede ser cualquier combinacin de letras, nmeros o un carcter de subrayado que no empiece por un nmero y sin espacios. Se puede cambiar el nombre mediante la propiedad Name. La configuracin de la aplicacin se puede almacenar como cualquier tipo de datos que sea XML serializable o que tenga un TypeConverter que implemente ToString/FromString. Los tipos ms comunes son String, Integer y Boolean, pero tambin puede almacenar valores como Color, Object, o bien como una cadena de conexin. La configuracin de la aplicacin tambin contiene un valor. El valor se establece mediante la propiedad Value y debe coincidir con el tipo de datos de la configuracin. Adems, la configuracin de la aplicacin se puede enlazar directamente a una propiedad de un formulario o de un control en tiempo de diseo. Hay dos tipos de configuracin de la aplicacin, en funcin del mbito: La configuracin de mbito de aplicacin se puede utilizar para obtener informacin como una direccin URL para un servicio Web o una cadena de conexin a bases de datos. Estos valores se asocian a la aplicacin; por tanto, los usuarios no pueden cambiarlos en tiempo de ejecucin. La configuracin de mbito de usuario se puede utilizar para obtener informacin como recordar la ltima posicin de un formulario o una preferencia de fuente. Los usuarios pueden modificar estos valores en tiempo de ejecucin. Puede cambiar el tipo de una configuracin con la propiedad Scope.

App.config Este archivo XML permite configurar las aplicaciones WPF. Si la aplicacin no contiene este archivo puede agregarse con la opcin Agregar Nuevo Elemento Archivo de Configuracin de Aplicaciones. En tiempo de diseo, existen dos maneras de crear la configuracin de la aplicacin: mediante la pgina Configuracin del Diseador de proyectos o desde la ventana Propiedades de un formulario o un control, lo que le permite enlazar una configuracin directamente a una propiedad. Cuando crea una configuracin con mbito de aplicacin (por ejemplo, una cadena de conexin a bases de datos o una referencia a los recursos del servidor), Visual Studio la guarda en un archivo app.config con la etiqueta <applicationSettings> (las cadenas de conexin se guardan en la etiqueta <connectionStrings>). Cuando crea una configuracin con mbito de usuario (por ejemplo, fuente predeterminada, pgina principal o tamao de la ventana), Visual Studio la guarda en un archivo app.config con la etiqueta <userSettings>. <?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" > 130

<section name="WpfCSharp.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" /> </sectionGroup> </configSections> <connectionStrings> <add name="WpfCSharp.Properties.Settings.AdvWorks" connectionString="Data Source=.;Initial Catalog=AdventureWorks;Integrated Security=True" providerName="System.Data.SqlClient" /> </connectionStrings> <userSettings> <WpfCSharp.Properties.Settings> <setting name="miClave" serializeAs="String"> <value>ElValor</value> </setting> </WpfCSharp.Properties.Settings> </userSettings> </configuration>

La configuracin de aplicacin consta de cuatro valores: Nombre: El nombre o identificacin del valor configurado. Se lo usa para acceder al valor. Tipo: El tipo de dato mbito: Puede ser Usuario o Aplicacin 131

Valor: El valor a devolver al leer la configuracin

Recuperando informacin de app.config Durante la ejecucin de la aplicacin necesitar acceder a los valores configurados en el archivo app.config. Para ello podr hacerlo desde el cdigo escribiendo un cdigo similar al siguiente, siendo AdvWorks el nombre del valor configurado: string sc = Properties.Settings.Default.AdvWorks;

Almacenar informacin en app.config en run-time Se puede almacenar informacin en el archivo de configuracin durante la ejecucin solo para valores configurados de mbito de usuario. Para cambiar el valor simplemente asgnele un nuevo valor y luego llame el mtodo Save. Properties.Settings.Default.miValor = "Otro Valor"; Properties.Settings.Default.Save();

2- Distribucin de Aplicaciones WPF


Una vez generadas las aplicaciones de Windows Presentation Foundation (WPF), es preciso implementarlas. Windows y .NET Framework incluyen varias tecnologas de implementacin: XCopy. Microsoft Windows Installer. Implementacin de ClickOnce.

XCopy La implementacin de XCopy se refiere al uso del programa de lnea de comandos XCopy para copiar los archivos de una ubicacin a otra. La implementacin de XCopy es adecuada en las siguientes circunstancias: Una aplicacin es autnoma; no necesita actualizar el cliente para ejecutarse. Los archivos la aplicacin se deben mover de una ubicacin a otra; por ejemplo, de la ubicacin de compilacin (disco local, recurso compartido de archivos UNC, etc.) a la ubicacin de publicacin (sitio web, recurso compartido de archivos UNC, etc.). Una aplicacin no requiere la integracin en el shell (acceso directo del men de Inicio, icono de escritorio, etc.). Aunque XCopy es adecuado para escenarios de implementacin simples, presenta limitaciones cuando se requieren funciones de implementacin ms complejas. En particular, al utilizar Xcopy se provoca una sobrecarga al crear, ejecutar y mantener los scripts necesarios para administrar la implementacin de una manera robusta. Adems, XCopy no admite el control de versiones, la desinstalacin ni la reversin.

Microsoft Windows Installer Windows Installer permite empaquetar las aplicaciones como aplicaciones ejecutables autnomas que se pueden distribuir con facilidad a los clientes y ejecutar. Adems, Windows Installer se instala con Windows y habilita la integracin con el escritorio, el men Inicio, y el panel de control Agregar o quitar programas. Windows Installer simplifica la instalacin y desinstalacin de aplicaciones, pero no proporciona los medios para asegurarse de que las aplicaciones instaladas se mantengan actualizadas desde el punto de vista de su versin. 132

ClickOnce ClickOnce habilita la implementacin de aplicaciones de tipo web para aplicaciones no web: las aplicaciones se publican e inician desde servidores web. Aunque ClickOnce no admite la gama completa de caractersticas de cliente que s poseen las aplicaciones instaladas con Windows Installer, admite un subconjunto que incluye lo siguiente: Integracin con el men Inicio y el panel de control Agregar o Quitar Programas, para aplicaciones independientes. Control de versiones, reversin y desinstalacin. Modo de instalacin en lnea, que siempre inicia una aplicacin desde la ubicacin de implementacin. Para hacer que una aplicacin ClickOnce est disponible para los usuarios, deber publicarla en un servidor Web, recurso compartido de archivo o en medios extrables. Puede publicar la aplicacin utilizando el Asistente para publicacin. Antes de ejecutar el Asistente para publicacin, debe establecer las propiedades de publicacin adecuadamente.

Publicacin ClickOnce Dentro de las propiedades del proyecto WPF tenemos una solapa Publicar. Podemos usar esta solapa para configurar la publicacin. Podemos elegir la ubicacin predetermina para la publicacin, el modo de instalacin, los archivos que forman parte de la aplicacin, cuales sern lo requisititos previos a la instalacin (verificacin de componentes que debern estar previamente instalados), si la instalacin soportar actualizaciones automticas, versionado, etc.

133

Como Publicar

1. En el Explorador de soluciones, seleccione el proyecto de la aplicacin. 2. Haga clic con el botn secundario en el nodo del proyecto y haga clic en Publicar. Aparecer el Asistente para publicacin. Tambin puede llamar al asistente de publicacin desde la solapa Publicar explicada anteriormente. Publicar en Web 3. En la pgina Dnde desea publicar la aplicacin?, escriba una direccin URL vlida con el formato http://www.microsoft.com/foldername y, a continuacin, haga clic en Siguiente. 4. En la pgina La aplicacin estar disponible sin conexin?, haga clic en la opcin adecuada: - Si desea permitir que se ejecute la aplicacin cuando el usuario est desconectado de la red, haga clic en S, esta aplicacin va a estar disponible con conexin o sin ella. Se crear un acceso directo en el men Inicio para la aplicacin. - Si desea ejecutar la aplicacin directamente desde la ubicacin de publicacin, haga clic en No, esta aplicacin slo est disponible en lnea. No se crear un acceso directo en el Men Inicio. Haga clic en Siguiente para continuar. 5. Haga clic en Finalizar para publicar la aplicacin. El estado de la publicacin se muestra en el rea de notificacin de estado. Recurso compartido de archivos 3. En la pgina Dnde desea publicar la aplicacin?, escriba una ruta de acceso vlida con el formato \\computername\applicationname y, a continuacin, haga clic en Siguiente. 4. En la pgina Instalacin de la aplicacin, seleccione la ubicacin donde los usuarios instalarn la aplicacin: - Si los usuarios van a instalar la aplicacin desde un sitio web, haga clic en Desde un sitio web y escriba una direccin URL que corresponda a la ruta de acceso del archivo escrita en el paso anterior. Haga clic en Siguiente. (Normalmente, se utiliza esta opcin 134

cuando se especifica una direccin FTP como la ubicacin de la publicacin. No se admite la descarga directa desde FTP. Por lo tanto, aqu debe escribir una direccin URL.) - Si los usuarios instalan la aplicacin directamente desde el recurso compartido de archivos, haga clic en Desde una ruta de acceso UNC o un recurso compartido de archivos y luego haga clic en Siguiente. (Esto es para ubicaciones de publicacin en el formato c:\deploy\myapp o \\server\myapp.) - Si los usuarios van a instalar la aplicacin desde medios extrables, haga clic en Desde un CD-ROM o un DVD-ROM y, a continuacin, haga clic en Siguiente. 5. En la pgina La aplicacin estar disponible sin conexin?, haga clic en la opcin adecuada: - Si desea permitir que se ejecute la aplicacin cuando el usuario est desconectado de la red, haga clic en S, esta aplicacin va a estar disponible con conexin o sin ella. Se crear un acceso directo en el men Inicio para la aplicacin. - Si desea ejecutar la aplicacin directamente desde la ubicacin de publicacin, haga clic en No, esta aplicacin slo est disponible en lnea. No se crear un acceso directo en el Men Inicio. Haga clic en Siguiente para continuar. 6. Haga clic en Finalizar para publicar la aplicacin. El estado de la publicacin se muestra en el rea de notificacin de estado. CD-ROM o DVD-ROM 3. En la pgina Dnde desea publicar la aplicacin?, escriba la ruta de acceso del archivo o ubicacin del FTP donde se publicar la aplicacin, por ejemplo d:\deploy. A continuacin, haga clic en Siguiente. 4. En la pgina Instalacin de la aplicacin, haga clic en Desde un CD-ROM o un DVD-ROM y, a continuacin, haga clic en Siguiente. 5. Si distribuye la aplicacin en CD-ROM, puede que desee proporcionar actualizaciones desde un sitio Web. En la pgina Dnde buscar la aplicacin las actualizaciones?, elija una opcin de actualizacin: - Si la aplicacin comprueba las actualizaciones, haga clic en la opcin La aplicacin buscar actualizaciones en la siguiente ubicacin y escriba la ubicacin donde se enviarn las actualizaciones. Puede ser una ubicacin de archivo, un sitio web o un servidor FTP. - Si la aplicacin no comprueba las actualizaciones, haga clic en la opcin La aplicacin no buscar actualizaciones. Haga clic en Siguiente para continuar. 6. Haga clic en Finalizar para publicar la aplicacin. El estado de la publicacin se muestra en el rea de notificacin de estado.

Comparacin entre ClickOnce y Microsoft Windows Installer Caracterstica ClickOnce Actualizacin automtica SI Deshacer cambios tras la instalacin SI Actualizar desde el Web SI No afecta a componentes compartidos u otras SI aplicaciones Se conceden permisos de seguridad Slo concede los permisos necesarios para la aplicacin (ms seguro) Permisos de seguridad requeridos Zona Internet o intranet (plena 135

Windows Installer SI NO NO NO Concede plena confianza de forma predeterminada (menos seguro) Administrador

confianza para la instalacin de CDROM) Firma de manifiestos de aplicacin e implementacin Interfaz de usuario del proceso de instalacin Instalacin de ensamblados a peticin Instalacin de archivos compartidos Instalacin de controladores Instalacin en la cach de ensamblados global Instalacin para varios usuarios Agregar la aplicacin al men Inicio Agregar la aplicacin al grupo Inicio Agregar la aplicacin al men Favoritos Registrar tipos de archivos Acceso al Registro durante la instalacin Revisin de archivos binarios Ubicacin de instalacin de aplicaciones SI Indicador nico SI NO NO NO NO SI NO NO NO Limitado NO Cach de aplicaciones de ClickOnce NO Asistente de varias partes NO SI S (con acciones personalizadas) SI SI SI SI SI SI SI SI Carpeta Archivos de programa

136

Links Relacionados
Introduccin a WPF http://msdn.microsoft.com/es-ar/library/aa970268.aspx Ejemplos Aplicaciones WPF: http://msdn.microsoft.com/es-ar/library/ms771449.aspx http://msdn.microsoft.com/es-ar/library/ms771542.aspx Informacin sobre controles http://msdn.microsoft.com/es-es/library/ms590941(v=VS.90).aspx Eventos y Comandos enrutados http://msdn.microsoft.com/es-es/magazine/cc785480.aspx Enlace a Datos http://msdn.microsoft.com/es-ar/magazine/cc163299.aspx http://channel9.msdn.com/posts/eliseta/WPF-para-desarrolladores/ http://www.csharpcorner.com/UploadFile/mahesh/GridViewWpf11082009182813PM/GridViewWpf.aspx http://www.elguille.info/colabora/2007/juanpablogc_wpf_gridview.htm Enlace a Colecciones http://msdn.microsoft.com/es-ar/library/ms752347.aspx#binding_to_collections Documentos http://msdn.microsoft.com/es-es/library/ms748388(VS.90).aspx http://msdn.microsoft.com/es-es/library/ms771612.aspx Graficos y multimedia http://msdn.microsoft.com/es-es/library/ms742562.aspx http://msdn.microsoft.com/es-es/library/ms748873.aspx http://msdn.microsoft.com/es-es/library/ms747437(v=VS.90).aspx http://msdn.microsoft.com/es-es/library/ms753347(VS.90).aspx http://msdn.microsoft.com/en-us/library/ms748248.aspx ClickOnce http://msdn.microsoft.com/es-es/library/142dbbz4(v=VS.90).aspx

137

You might also like