desarrollo de aplicaciones con wpf

Post on 15-Jun-2015

1.878 Views

Category:

Technology

11 Downloads

Preview:

Click to see full reader

DESCRIPTION

Introducción al desarrollo de aplcaciones con WPF (Windows Presentation Foundation), la cual utiliza la tecnología XAML (eXtensible Application Markup Language), haciendo uso simple del patrón de diseño orientado a plataformas XAML y consumo de datos de una api publica. Aplicación de ejemplo desarrollada dentro de la presentación.

TRANSCRIPT

Desarrollo de aplicaciones con WPF

(Windows Presentation Foundation)José Alberto Rubalcaba Velázquez

Es un framework de nueva generación que cuenta con la integración de varios frameworks como GDI (Graphic Device Interface) y GDI+, influenciado fuertemente por kits de herramientas para Web, como lo son Adobe Flash

Podemos crear aplicaciones con experiencia de usuario visualmente satisfactoria

Que es WPF?

WPF existe como una gran parte del framework de .NET que están ubicados en su mayor parte en el espacio de nombres de System.Windows

Si se cuenta con experiencia en ASP.NET o Windows Forms, la programación con WPF te sonará familiar; se instancian clases, asignas propiedades, mandas a llamar métodos y manejar eventos, todo por medio de tu lenguaje de programación favorito: C# o VB

Programando con WPF

Podemos crear una separación entre la lógica y la apariencia de nuestra aplicación, obteniendo los siguientes beneficios:

Costos de desarrollo y mantenimiento son reducidos, ya que la apariencia no esta fuertemente ligada con el comportamiento de la aplicación.

Programando con WPF

El desarrollo es mas eficiente, ya que los diseñadores pueden estar trabajando en la apariencia de la aplicación mientras desarrolladores trabajan en el comportamiento.

Podemos usar múltiples herramientas de diseño para nuestras aplicaciones como Microsoft Expression.

Globalizacion y localización para aplicaciones con WPF se ha simplificado (Globalización y Localización con WPF)

Programando con WPF

Es un lenguaje de marcado basado en XML para implementar la apariencia de una aplicación declarativamente.

Se usa para crear ventanas, diálogos, páginas, controles de usuario, dibujos y/o gráficas.

Se usa para el diseño de vistas para Workflow markup, Windows Phone 7 y 8, Aplicaciones para Windows Store, y mas !

XAML (eXtensible Application Markup Language)

Mismas reglas que en XML

oDebe de existir un nodo raízoTodo elemento debe de cerraroSensible a mayúsculas y minúsculas oExisten elementos y subelementosoExisten atributos para cada elemento

Reglas básicas de XAML

Los elementos instancian un objeto<Rectangle />

Los atributos cambian las características de los objetos<Rectangle Width=“100” Height=“100” />

El anidamiento implica pertenencia <Grid>

<Rectangle /> </Grid>

Reglas básicas de XAML

A todo elemento declarado en XAML, le debe de corresponder a una clase dentro del espacio de nombres de la API de .NET◦ Por ejemplo

Reglas basicas XAML

Elemento XAML Clase

<Rectangle /> System.Windows.Shapes.Rectangle

<Button /> System.Windows.Controls.Button

<ListBox /> System.Windows.Controls.ListBox

Se usan para organizar lógicamente las claseshttp://schemas.microsoft.com/winfx/2006/xaml/presentation◦ Espacio de nombres base. Abarca todos los

espacios de nombres CLR (Common Language Runtime)

http://schemas.microsoft.com/winfx/2006/xamlEspacio de nombres de XAML

Espacios de nombres en XAML

El atributo xmlns importa un espacio de nombres XML para dejar a nuestro alcance todos los miembros incluidos en el

Es similar a una sentencia using en C# o Imports en VB

Podemos asignar de manera opcional un alias a nuestros espacios de nombres (xmlns:alias)

Espacios de nombres en XAML

Se puede establecer el atributo xmlns en cualquier nivel de nuestra aplicación

Lo mas conveniente es colocar el espacio de nombres en la raíz de la página o ya sea de la aplicación

<Grid xmlns:ans=http://schemas.microsoft.com/winfx/2006/xaml/presentation>

<ans:Button Width=“200” Height=“100” Content=“Click me!” />

</Grid>

Espacios de nombres en XAML

Todas las propiedades se pueden establecer como subelementos dentro de un documento XAML

Es necesario únicamente cuando el valor de una propiedad es un objeto complejo y no se cuenta con un convertidor de tipo

<Rectangle Width=“100” Height=“100” Fill=“Yellow” />

es lo mismo que:

<Rectangle><Rectangle.Width>100</Rectangle.Width><Rectangle.Height>100</Rectangle.Height><Rectangle.Fill>Yellow</Rectangle.Fill>

</Rectangle>

Sintaxis de subelementos

Son clases que permiten al intérprete de XAML el evaluar de distintas maneras sus valores◦ {StaticResource}◦ {Binding}◦ {TemplateBinding}◦ {RelativeSource}◦ {x:Null}

Sintáxis:<Element property=“{Extensión [Properties]}” />

Extensiones de marcado

Se refieren a una bolsa de propiedades La clase FrameworkElement implementa la

propiedad Resources◦ Permite guardar cualquier tipo de objeto para

reutilizarlo◦ Se identifican por medio de una cláve única

(atributo x:Key)

<Grid.Resources><SolidColorBrush x:Key=“myBrush”

Color=“Red” /></Grid.Resources>

Recursos

Se referencían en XAML por medio de la extensión {StaticResource}

{StaticResource} puede ser usada en propiedades regulares CLR<Window.Resources>

<SolidColorBrush x:Key=“myBrush”Color=“Red” />

</Window.Resources><Rectangle Width=“100” Height=“100”

Fill=“{StaticResource myBrush}” />

Recursos

Recursos via código◦ Dentro del código de la aplicación usamos la propiedad

Resources para leer o agregar objetos al diccionario de recursos

◦ La propiedad Resources es un diccionario del tipo <object,object>

Private void Button_Click(object sender, RoutedEventArgs e){

if(this.Resources.Contains(“myBrush”)// obtenemos el recursovar brush = this.Resources[“myBrush”] as

SolidColorBrush;//agregamos un recurso this.Resources.Add(“resource”, resourceObject);

}

Recursos

Tipo especial de propiedad dependiente

Notifican al elemento padre que se requiere cierto valor

Sintáxis XAML

<ParentClass>

<Element ParentClass.Property = “Value” /></ParentClass>

Propiedades adjuntas

Se pueden utilizar los métodos SetValue() y GetValue() como en cualquier otra propiedad dependienteif ((double) rect.GetValue(Grid.Column) == 1){

rect.SetValue(Grid.Column, 2);}

Se pueden usar los métodos para leer o establecer los valores de las propiedades adjuntas

if (Grid.GetColumn(rect) == 1){

Grid.SetColumn(rect, 2);}

Propiedades adjuntas

Contenedores visuales

Clases que heredan de la clase base Panel◦ Canvas ◦ StackPanel◦ Grid

Otros◦ Border◦ ScrollViewer

Contenedores

Contenedor básico de posicionamiento absoluto

Propiedades adjuntas◦ Left◦ Right◦ Top◦ Bottom

Canvas

Véase el siguiente fragmento de código:<Canvas>

<Rectangle Width=”100” Height=“100”Canvas.Left=“50” Canvas.Top=“50” Fill=“Blue” />

<Rectangle Width=”100” Height=“100”Canvas.Left=“50” Canvas.Top=“50”

Fill=“Orange”/></Canvas>

Ejemplo Canvas

¿Qué obtenemos?

Contenedor para apilar elementos de manera horizontal o vertical

Útil en escenarios donde necesites alinear controles◦ Casos como un menú, una barra de botones, etc

StackPanel

Véase el siguiente fragmento de código:<StackPanel>

<Rectangle Width=”150” Height=“150”Fill=“Blue” />

<Rectangle Width=”150” Height=“150”Fill=“Orange”/>

</StackPanel>

Ejemplo StackPanel

¿Qué obtenemos?

Contenedor de tipo tabla

Es el más flexible de todos los contenedores

Permite definir columnas y filas

Propiedades adjuntas:◦ Column◦ Row◦ ColumnSpan◦ RowSpan

Grid

Los altos y anchos de filas y columnas pueden ser de 3 tipos:

◦ Fijo Se mide en pixeles

◦ Automático En función de su contenido

◦ Proporcional(*) Predeterminado

Grid

Véase el siguiente fragmento de código<Grid> <Grid.RowDefinitions> <RowDefinition Height="110"/> <RowDefinition Height=“Auto"/> <RowDefinition Height=“*"/> </Grid.RowDefinitions>

<Grid.ColumnDefinitions> <ColumnDefinition Height=“110”/> <ColumnDefinition Height=“Auto”/> <ColumnDefinition Height=“*”/> </Grid.ColumnDefinitions>

<Rectangle Width="100" Height="100" Fill="Blue" Grid.Column="0" Grid.Row="0"/>

<Rectangle Width="100" Height="100" Fill="Blue" Grid.Column="1" Grid.Row="1"/>

<Rectangle Width="100" Height="100" Fill="Blue" Grid.Column="2" Grid.Row="2"/>

</Grid>

Ejemplo Grid

¿Qué obtenemos?

Propiedades de distribución dinámica para contenedores excepto Canvas

◦ HorizontalAlignment y VerticalAlignment◦ Margin◦ MaxWidth◦ MaxHeight◦ MinWidth◦ MinHeight

Propiedades de distribución

System.Windows.Shapes Propiedades

◦ Fill◦ Stroke◦ StrokeThickness◦ StrokeDashCap◦ StrokeDashOffset

Clase Shape

System.Windows.Shapes◦ Ellipse◦ Rectangle◦ Line◦ Polyline◦ Polygon◦ Path

Formas básicas

System.Windows.Controls Clase para representar una imagen Similar al elemento <img> de HTML Puede tener una fuente absoluta o relativa Soporta solo imágenes png y jpg

<Image Source=“someImg.png”/>

<Image Source=“http://www.somepage.com/someImg.jpg” />

Image

System.Windows.Controls Elemento principal para mostrar texto en

las aplicaciones XAML Soporta cambiar el tamaño de la fuente, el

tipo, las decoraciones, alineaciones, etc Run

◦ Permite estilizar partes del texto de un TextBlock LineBreak

◦ Salto de línea explícito

TextBlock

Véase el siguiente fragmento de código

<TextBlock FontSize="50" TextWrapping="Wrap"> <Run Foreground="Blue">Taller</Run> de desarrollo de aplicaciones

<LineBreak /> con <Run Foreground="Gold">WPF</Run>

<LineBreak /> <Run Foreground="Red">Semana ISW</Run>

</TextBlock>

Ejemplo

¿Qué se obtiene?

Enlace de datos

Enlace de datos

Modelo robusto◦ Objeto fuente

Propiedad en el objeto fuente

◦ Control destino Propiedad en el control destino

Se expresan a través de la extensión del Markup {Binding}

<TextBlock Text=“{Binding Source={StaticResource User}, Path=UserName}” />

Enlace de datos

Parámetros principales de {Binding}◦ Source

Indica el objeto fuente

◦ Path Indica una ruta a la propiedad en el objeto fuente Parámetro predeterminado

◦ Mode Indica el modo para el enlace

Enlace de datos

OneTime◦ El enlace se establece y el objeto fuente y el

control destino no se vuelven a comunicar entre sí OneWay

◦ El enlace se establece y cuaquier cambio que suceda en el objeto fuente le avisará al control destino

TwoWay◦ El enlace se establece y cuaquier cambio que

suceda en el objeto fuente le avisará al control destino y viceversa (bi-direccional)

Modos de enlace

Se expresan a través del atributo Mode

<TextBlock Text=“{Binding

Source={StaticResource User},Path=UserName,Mode=TwoWay}” />

Modos de enlace

Los modos OneWay y TwoWay requieren que el objeto fuente implemente alguna de las interfaces INotifyPropertyChanged o INotifyCollectionChanged◦ Implementan un evento, el cual es escuchado en

la infraestructura de enlace de datos◦ INotifyPropertyChanged en objetos

individuales, para notifucar que una propiedad ha cambiado

◦ INotifyCollectionChanged en colecciones, para notificar que una colección ha cambiado

Interfaces

Windows Presentation Foundation soporta el atributo CallerMemberName

◦ Obtiene automáticamente el nombre del método o propiedad que mandó a llamar al método en cuestión

◦ Se evita el uso de “cadenas mágicas”, lo cual no dificulta el dar mantenimiento a las aplicaciones

◦ Disponible en System.Runtime.CompilerServices

Interfaces

Clase base que implementa INotifyPropertyChanged

protected virtual void OnPropertyChanged([CallerMemberName]

string propertyName = null)

{

If(PropertyChanged != null)

{

PropertyChanged(this, new PropertyChangedEventArgs(propertyName));

}

}

Interfaces

Colección genérica recomendada para escenarios de enlace de datos

Implementa INotifyPropertyChanged y INotifyCollectionChanged

Automáticamente actualiza el control de lista que esté enlazada

Disponible en System.Collections.ObjectModel

ObservableCollection<User> …

ObservableCollection<T>

Expresan el XAML que representa a cada uno de los elementos en un control, lo podemos usar en listas, botones, etc

Se expresan con el elemento DataTemplate o ControlTemplate

Se declaran en linea junto con el elemento a personalizar, o dentro del diccionario de recursos de la pagina o aplicación

Plantillas de datos

<Button > <Button.Template> <ControlTemplate> <StackPanel Orientation="Horizontal"> <Image Source="BB.jpg" /> <StackPanel> <TextBlock Text="Click me"/> <TextBlock Text="Right now!"/> </StackPanel> </StackPanel> </ControlTemplate> </Button.Template> </Button>

Plantillas de datos

Clases que implementan la interfaz IValueConverter

La interfaz IValueConverter incluye dos métodos a implementar:

◦ Convert Método que se ejecuta cuando el valor fluye del

objeto fuente hacia el control destino◦ ConvertBack

Método que se ejecuta cuando el valor fluye de regreso: del control destino hacia el objeto fuente

Convertidores de valor

Son “funcionalidad enlazable” Clases que implementan la interfaz

ICommand Soportados por la familia de clases

ButtonBase Miembros:

◦ Execute: Indica qué acción se realizará◦ CanExecute: Determina si el comando puede

ejecutar◦ CanExecuteChanged: Re-evalúa CanExecute

Comandos

Model-View-ViewModel

Patrón de diseño natural para plataformas XAML◦ Aprovecha al máximo el enlace de datos {Binding}

Ventajas◦ Separacion de concerns (preocupaciones)◦ Pruebas unitarias ◦ Mantenimiento de código◦ Consistencia◦ Desacoplamiento◦ Flujo de trabajo entre diseñadores y desarrolladores◦ Reutilización de código◦ ..y muchos beneficios mas..

¿Qué es MVVM?

¿Cómo trabaja MVVM?

View100% Declarative via XAML

ViewModelExposes Model to View for data binding

Exposes logic to user via data bound ICommandsApplication-specific state and logic

ModelDomain specific entities and operationsContains no knowledge of specific usage

Data binding of commands

Data binding of properties

Direct access via code

View◦ Define la interfaz de usuario◦ Define la estructura y apariencia de lo que el

usuario ve en la pantalla◦ Estilos, recursos◦ El contexto de datos es el ViewModel◦ Poco o nada de code-behind

Solo código que no necesite pruebas unitarias◦ Comportamientos◦ Actualizada a través de Bindings

MVVM

ViewModel◦ Es una abstracción de la Vista◦ Implementa la lógica de presentación◦ Adapta el modelo a la vista◦ Mantiene el estado◦ Expone propiedades a las que se enlaza la vista

(datos y comandos)◦ Expone metodos que los comportamientos de una

vista puede invocar◦ Desacoplamiento y Testability es el objetivo

principal del ViewModel

MVVM

Model

◦ Tu dominio◦ Objetos de datos

DTO, POCO Modelo de datos generado Modelo de proxy generado

◦ Capa de servicios Repositorios Objetos negocio

MVVM

Cardinalidad

◦ Generalmente, una vista solo tiene un ViewModel

◦ Un ViewModel puede ser usado en una o más vistas

◦ Un Model puede ser usado en uno o mas ViewModels

MVVM

Estrategias para relacionar View con ViewModel◦ Primero la vista (View first)

La vista creal el ViewModel (en XAML o code-behind) La vista tiene inyectado el ViewModel (propiedad o

constructor)

◦ Primero el ViewModel (ViewModel first) El ViewModel crea la vista, se enlaza a sí mismo a la

vista

MVVM

Para cambiar una vista, siempres se debe de implementar una propiedad en el ViewModel◦ Para deshabilitar un boton: enlaza una propiedad◦ Para cambiar el estado de la vista: enlaza una

propiedad◦ Para iniciar alguna animación: enlaza una propiedad◦ Para mostrar errores de validación: enlaza una

propiedad Para que la vista ejecute código

◦ Los controles de la vista se enlazan a propiedades de tipo ICommand

◦ Los comportamientos de la vista pueden invocar métodos o enlazar un evento a un comando

MVVM

Arquitectura de tu aplicación

MVVM

Si recapitulamos◦ La vista es XAML◦ La vista puede tener code-behind

Solo el código relacionado con la UI◦ La vista mantiene una referencia al ViewModel◦ La vista se enlaza al ViewModel◦ La vista utiliza comandos para invocar métodos

en el ViewModel◦ La vista utiliza comportamientos para invocar

metodos en el ViewModel◦ El ViewModel mantiene una referencia al Model

MVVM

Crea un proyecto nuevo de Visual Studio 2012

Construyamos una app !!

Dale el nombre WorkshopApp

Observa la arquitectura de tu proyecto

Construyamos una app !!

Agrega 3 folders con los nombres Models, ViewModels y Views, la vista llamada MainWindow arrástrala al folder Views

Ahora abre tu documento

App.xaml

Construyamos una app !!

Cambia el StartupUri de la aplicación al de la vista que está en el folder Views

Construyamos una app !!

Da click derecho sobre el proyecto y selecciona la opción Manage NuGet Packages ◦ Busca el paquete llamado HttpClient e instálalo,

aceptando los términos y condiciones

Construyamos una app !!

Model◦ Crea una clase pública llamada New con las

siguientes propiedades

Construyamos una app !!

Model◦ Crea una clase pública llamada NewsEventArgs

que herede de la clase base EventArgs.◦ Este evento debe de guardar una lista de noticias,

resultado de un consumo de datos de una API de noticias

Construyamos una app !!

Model◦ Crea una clase llamada NewsService y agrega un

manejador de eventos para NewsEventArgs

◦ Agrega una constante llamada NewsUriFormat con la siguiente cadena

“http://apiservice.univision.com/rest/feed/getFeed?url=%2Fsearch%2Farticles%3Fcount%3D{1}%26site%3Dnoticias%26tags%3D{0}%26outputMode%3Dxml&api_key={2}”

Construyamos una app !!

Model◦ Crea una funcion llamada GetNews que reciba una cadena como

parámetro.◦ Usaremos la clase XDocument para procesar la respuesta en formato

XML por medio de un query

Construyamos una app !!

ViewModel◦ Crea una clase llamada ActionCommand que

implemente las funciones de ICommand.◦ Crea una propiedad a nivel de clase del tipo

Action y que sea recibida por medio del constructor.

◦ La función CanExecute devolverá un valor verdadero

◦ La función Execute debera ejecutar la acción definida como propiedad

Construyamos una app !!

ViewModel◦ Crea una clase pública llamada BaseViewModel

que implemente la interface INotifyPropertyChanged, ésta clase sera la base para todos los ViewModels, recuerda usar el atributo CallerMemberName

Construyamos una app !!

ViewModel◦ Ahora crea una clase pública llamada NewsViewModel, ésta debe de

heredar de la clase base BaseViewModel

◦ Encapsula las propiedades que desees enlazar a la vista de la aplicación (en este caso crearás una propiedad llamada city y en el accesor set llama a la función OnPropertyChanged para notificar el cambio)

◦ Sigue el mismo procedimiento con con una propiedad del tipo ObservableCollection<New>

Construyamos una app !!

ViewModel◦ Crea una propiedad privada de la clase

NewsService, e inicializala dentro del constructor del ViewModel junto con el manejador del evento GetNewsCompleted

Construyamos una app !!

ViewModel◦ Crea una propiedad de la clase ActionCommand y encapsúlala, se debe

de crear una clase por cada comando deseado dentro de la vista

◦ Dentro del accesor get, checa que si el campo no es nulo, de ser así, crea una nueva instancia del campo getNewsCommand, asignandole una acción por medio de una expresión lambda

◦ Dentro del cuerpo de la acción, manda a llamar la funcion GetNews, que pertenece a la propiedad del tipo NewsService

Construyamos una app !!

View◦ Importemos el espacio de nombres de

ViewModels a la ventana XAML

◦ Creemos una instancia de NewsViewModel dentro del diccionario de recursos de la ventana

Construyamos una app !!

View◦ Dividimos en dos filas nuestro Grid principal, y le

asigamos a la propiedad DataContext el ViewModel alojado en el diccionario de recursos

Construyamos una app !!

View◦ A la primera fila le agregamos una caja de búsqueda y un botón para

iniciar una búsqueda de noticias, enlazandolo a nuestro comando de noticas; podemos usar algún DataTemplate para darle estilo a nuestro botón

Construyamos una app !!

View◦ A la segunda fila le agregamos un elemento

ListBox, el cual estará enlazado a nuestra lista de noticias en el ViewModel, creando un ItemTemplate para cada elemento en el ListBox

Construyamos una app !!

Resultado

top related