Está en la página 1de 81

Desarrollo de

aplicaciones con WPF


(Windows Presentation Foundation)
Jos Alberto Rubalcaba Velzquez

Que es WPF?

Es un framework de nueva generacin que


cuenta con la integracin 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

Programando con WPF

WPF existe como una gran parte del framework


de .NET que estn 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 programacin con WPF te
sonar familiar; se instancian clases, asignas
propiedades, mandas a llamar mtodos y
manejar eventos, todo por medio de tu lenguaje
de programacin favorito: C# o VB

Programando con WPF

Podemos crear una separacin entre la lgica y la


apariencia de nuestra aplicacin, obteniendo los
siguientes beneficios:

Costos de desarrollo y mantenimiento son


reducidos, ya que la apariencia no esta
fuertemente ligada con el comportamiento de la
aplicacin.

Programando con WPF

El desarrollo es mas eficiente, ya que los


diseadores pueden estar trabajando en la
apariencia de la aplicacin mientras
desarrolladores trabajan en el comportamiento.

Podemos usar mltiples herramientas de diseo


para nuestras aplicaciones como
Microsoft Expression.

Globalizacion y localizacin para aplicaciones con


WPF se ha simplificado (Globalizacin y
Localizacin con WPF)

XAML (eXtensible Application


Markup Language)

Es un lenguaje de marcado basado en XML para


implementar la apariencia de una aplicacin
declarativamente.

Se usa para crear ventanas, dilogos, pginas,


controles de usuario, dibujos y/o grficas.

Se usa para el diseo de vistas para


Workflow markup, Windows Phone 7 y 8,
Aplicaciones para Windows Store, y mas !

Reglas bsicas de XAML

Mismas reglas que en XML


o Debe de existir un nodo raz
o Todo elemento debe de cerrar
o Sensible a maysculas y minsculas
o Existen elementos y subelementos
o Existen atributos para cada elemento

Reglas bsicas de XAML

Los elementos instancian un objeto


<Rectangle />

Los atributos cambian las caractersticas de los


objetos
<Rectangle Width=100 Height=100 />

El anidamiento implica pertenencia


<Grid>
<Rectangle />
</Grid>

Reglas basicas 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
Elemento XAML

Clase

<Rectangle />

System.Windows.Shapes.Rectangle

<Button />

System.Windows.Controls.Button

<ListBox />

System.Windows.Controls.ListBox

Espacios de nombres en
XAML

Se usan para organizar lgicamente las clases


http://schemas.microsoft.com/winfx/2006/xaml/pr
esentation
Espacio de nombres base. Abarca todos los
espacios de nombres CLR (Common Language
Runtime)
http://schemas.microsoft.com/winfx/2006/xaml
Espacio 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 aplicacin

Lo mas conveniente es colocar el espacio de


nombres en la raz de la pgina o ya sea de la
aplicacin

<Grid xmlns:ans=
http://schemas.microsoft.com/winfx/2006/xaml
/presentation>
<ans:Button Width=200 Height=100
Content=Click me! />
</Grid>

Sintaxis de subelementos
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>

Extensiones de marcado

Son clases que permiten al intrprete de XAML el


evaluar de distintas maneras sus valores

{StaticResource}
{Binding}
{TemplateBinding}
{RelativeSource}
{x:Null}

Sintxis:
<Element property={Extensin [Properties]} />

Recursos

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 clve nica
(atributo x:Key)
<Grid.Resources>
<SolidColorBrush x:Key=myBrush
Color=Red />
</Grid.Resources>

Recursos

Se referencan en XAML por medio de la


extensin {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 cdigo


Dentro del cdigo de la aplicacin 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 recurso
var brush = this.Resources[myBrush] as
SolidColorBrush;
//agregamos un recurso
this.Resources.Add(resource, resourceObject);
}

Propiedades adjuntas

Tipo especial de propiedad dependiente

Notifican al elemento padre que se requiere


cierto valor

Sintxis XAML
<ParentClass>
<Element ParentClass.Property = Value />
</ParentClass>

Propiedades adjuntas

Se pueden utilizar los mtodos SetValue() y GetValue()


como en cualquier otra propiedad dependiente
if ((double) rect.GetValue(Grid.Column) == 1)
{
rect.SetValue(Grid.Column, 2);
}

Se pueden usar los mtodos para leer o establecer los


valores de las propiedades adjuntas
if (Grid.GetColumn(rect) == 1)
{
Grid.SetColumn(rect, 2);
}

Contenedores

Contenedores visuales

Clases que heredan de la clase base Panel


Canvas
StackPanel
Grid

Otros
Border
ScrollViewer

Canvas

Contenedor bsico de posicionamiento


absoluto

Propiedades adjuntas

Left
Right
Top
Bottom

Ejemplo Canvas

Vase el siguiente fragmento de cdigo:


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

Qu obtenemos?

StackPanel

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

Ejemplo StackPanel

Vase el siguiente fragmento de cdigo:


<StackPanel>
<Rectangle Width=150 Height=150
Fill=Blue />
<Rectangle Width=150 Height=150
Fill=Orange/>
</StackPanel>

Qu obtenemos?

Grid

Contenedor de tipo tabla

Es el ms 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

Automtico
En funcin de su contenido

Proporcional(*)
Predeterminado

Ejemplo Grid
Vase el siguiente fragmento de cdigo
<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"
<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>

Grid.Row="0"/>

Qu obtenemos?

Propiedades de
distribucin

Propiedades de distribucin dinmica para


contenedores excepto Canvas

HorizontalAlignment y VerticalAlignment
Margin
MaxWidth
MaxHeight
MinWidth
MinHeight

Clase Shape
System.Windows.Shapes
Propiedades

Fill
Stroke
StrokeThickness
StrokeDashCap
StrokeDashOffset

Formas bsicas

System.Windows.Shapes

Ellipse
Rectangle
Line
Polyline
Polygon
Path

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

<Image Source=someImg.png/>

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

TextBlock
System.Windows.Controls
Elemento principal para mostrar texto en
las aplicaciones XAML
Soporta cambiar el tamao de la fuente, el
tipo, las decoraciones, alineaciones, etc
Run

Permite estilizar partes del texto de un TextBlock

LineBreak
Salto de lnea explcito

Ejemplo

Vase el siguiente fragmento de cdigo

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

Qu se obtiene?

Enlace de datos

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 travs de la extensin del


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

Enlace de datos

Parmetros principales de {Binding}


Source
Indica el objeto fuente

Path
Indica una ruta a la propiedad en el objeto fuente
Parmetro predeterminado

Mode
Indica el modo para el enlace

Modos de enlace

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 travs del atributo Mode


<TextBlock
Text={Binding
Source={StaticResource User},
Path=UserName,
Mode=TwoWay} />

Interfaces

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 coleccin ha cambiado

Interfaces

Windows Presentation Foundation soporta el


atributo CallerMemberName
Obtiene automticamente el nombre del mtodo
o propiedad que mand a llamar al mtodo en
cuestin
Se evita el uso de cadenas mgicas, 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));
}
}

ObservableCollection<T>
Coleccin genrica recomendada para
escenarios de enlace de datos
Implementa INotifyPropertyChanged y
INotifyCollectionChanged
Automticamente actualiza el control de
lista que est enlazada
Disponible en
System.Collections.ObjectModel

ObservableCollection<User>

Plantillas de datos
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 aplicacin

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>

Convertidores de valor
Clases que implementan la interfaz
IValueConverter
La interfaz IValueConverter incluye dos
mtodos a implementar:

Convert
Mtodo que se ejecuta cuando el valor fluye del
objeto fuente hacia el control destino

ConvertBack
Mtodo que se ejecuta cuando el valor fluye de
regreso: del control destino hacia el objeto fuente

Comandos
Son funcionalidad enlazable
Clases que implementan la interfaz
ICommand
Soportados por la familia de clases
ButtonBase
Miembros:

Execute: Indica qu accin se realizar


CanExecute: Determina si el comando puede
ejecutar
CanExecuteChanged: Re-evala CanExecute

Model-ViewViewModel

Qu es MVVM?

Patrn de diseo natural para plataformas XAML


Aprovecha al mximo el enlace de datos {Binding}

Ventajas

Separacion de concerns (preocupaciones)


Pruebas unitarias
Mantenimiento de cdigo
Consistencia
Desacoplamiento
Flujo de trabajo entre diseadores y desarrolladores
Reutilizacin de cdigo
..y muchos beneficios mas..

Cmo trabaja MVVM?


View
100% Declarative via XAML

Data binding
of commands

Data binding
of properties

ViewModel
Exposes Model to View for data binding
Exposes logic to user via data bound ICommands
Application-specific state and logic
Direct access
via code

Model
Domain specific entities and operations
Contains no knowledge of specific usage

MVVM

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 cdigo que no necesite pruebas unitarias

Comportamientos
Actualizada a travs de Bindings

MVVM

ViewModel

Es una abstraccin de la Vista


Implementa la lgica de presentacin
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 ms
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 animacin: enlaza una propiedad
Para mostrar errores de validacin: enlaza una
propiedad

Para que la vista ejecute cdigo


Los controles de la vista se enlazan a propiedades de tipo
ICommand
Los comportamientos de la vista pueden invocar mtodos
o enlazar un evento a un comando

MVVM

Arquitectura de tu aplicacin

MVVM

Si recapitulamos
La vista es XAML
La vista puede tener code-behind
Solo el cdigo relacionado con la UI

La vista mantiene una referencia al ViewModel


La vista se enlaza al ViewModel
La vista utiliza comandos para invocar mtodos
en el ViewModel
La vista utiliza comportamientos para invocar
metodos en el ViewModel
El ViewModel mantiene una referencia al Model

Construyamos una app !!

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 arrstrala al folder Views
Ahora abre tu documento
App.xaml

Construyamos una app !!

Cambia el StartupUri de la aplicacin al de


la vista que est en el folder Views

Construyamos una app !!

Da click derecho sobre el proyecto y


selecciona la opcin Manage NuGet
Packages
Busca el paquete llamado HttpClient e instlalo,
aceptando los trminos y condiciones

Construyamos una app !!

Model
Crea una clase pblica llamada New con las
siguientes propiedades

Construyamos una app !!

Model
Crea una clase pblica 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
parmetro.
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 funcin CanExecute devolver un valor
verdadero
La funcin Execute debera ejecutar la accin
definida como propiedad

Construyamos una app !!

ViewModel
Crea una clase pblica 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 pblica llamada NewsViewModel, sta debe de
heredar de la clase base BaseViewModel
Encapsula las propiedades que desees enlazar a la vista de la aplicacin
(en este caso crears una propiedad llamada city y en el accesor set
llama a la funcin 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 encapslala, 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 accin por medio de una expresin lambda
Dentro del cuerpo de la accin, 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 bsqueda y un botn para
iniciar una bsqueda de noticias, enlazandolo a nuestro comando de
noticas; podemos usar algn DataTemplate para darle estilo a nuestro
botn

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

Resultado

También podría gustarte