MVVMBasicDemo1: Patrón de diseño MVVM con aplicaciones basadas en WPF Resultado de imagen de WPF (Windows Presentation Foundation)

WPF (Windows Presentation Foundation) es una tecnología de MS para diseñar interfaces de usuario tomando ideas de técnicas Web y aplicaciones Windows. WPF permite definir las ventanas en ficheros de texto plano que contienen un lenguaje de etiquetado llamado XAML (basado en XML).

El proyecto completo se puede descargar en GitHub: https://github.com/ikerlandajuela/MVVMBasicDemo1.

 

De está forma separa las capas con la lógica de la aplicación y la capa de presentación donde interactuamos con el usuario. Está separación tan nítida propicia adoptar patrones de diseño como MVVM (Model-View-ViewModel ) para desarrollar aplicaciones complejas.

WPF emplea data-binding para conectar  la UI (User Interface) con la lógica de la aplicación, gracias a ello cuando un origen de dato cambia su valor  el cambio se refleja de forma automática en la UI, también si a la inversa la presentación del dato cambia en la UI los cambios tienen reflejo en la lógica de negocio interna (el contenido de un TextBox modificado por el usuario por ejemplo) .

El modelo MVVM estructura la aplicación en 3 capas:

  • Model: Mantiene los orígenes de datos.
  • ViewModel: Actúa de conector entre las otras dos capas.
  • View: Mantiene la información de la UI.

MVVMBasicDemo1: Primera aplicación

Este es el ejemplo mas sencillo que he encontrado para entender los fundamentos básicos de MVVM con WPF.  La única ventana de la aplicación muestra el nombre y apellido (cada uno en su respectivo TextBox editable) de una lista de estudiantes, junto a los dos TexBox (FirstName y LastName) hay un TextBlock con el nombre y apellidos unidos (FullName), cuando el usuario modifica el nombre o apellido de un estudiante inmediatamente la modificación se actualiza de forma automática en el TexBox (de lectura). Los controles con la lista de usuarios se crean de forma dinámica dependiendo de la lista de estudiantes que proporcionemos en la capa ViewModel.

 

Creamos un nuevo proyecto de tipo “WPF Application” en VS (Visual Studio). Creamos 3 carpetas (Model, ViewModel, Views)

Model

Añadimos una nueva clase “StudentModel” a la carpeta “Model”.

Para poder usar las técnicas de programación que se describen a continuación debemos añadir al comienzo del fichero un nuevo espacio de nombres System.ComponentModel.

using System.ComponentModel;

La clase base ‘INotifyPropertyChanged‘ notifica que el valor de una propiedad ha cambiado, genera un evento PropertyChanged cuando cambia el valor de un miembro de la clase. Debemos definir un atributo de tipo PropertyChangedEventHandler como manejador del evento para notificar a las clases cuando cambia una propiedad en alguno de los atributos editables (firstName,lastName).

Los atributos privados de la clase son el nombre y apellido, controlamos el acceso a sus propiedades con los descriptores de acceso get/set (ver más sobre este tema en “C# class LibroCalificaciones: Acceso a propiedades con descriptores de acceso get / set“), de esta forma controlamos cuando cambia el valor y lanzamos la función RaisePropertyChanged que a su vez llama a al manejador PropertyChanged. El resto de código y comprobaciones que realiza con fáciles de comprender. Si por ejemplo cambia el nombre genera un evento adicional para que en coherencia cambie el FullName.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.ComponentModel;

namespace MVVMBasicDemo1.Model
{
public class StudentModel { }

public class Student : INotifyPropertyChanged
{
private string firstName;
private string lastName;

public string FirstName
{
get
{
return firstName;
}

set
{
if (firstName != value)
{
firstName = value;
RaisePropertyChanged("FirstName");
RaisePropertyChanged("FullName");
}
}
}

public string LastName
{
get { return lastName; }

set
{
if (lastName != value)
{
lastName = value;
RaisePropertyChanged("LastName");
RaisePropertyChanged("FullName");
}
}
}

public string FullName
{
get
{
return firstName + " " + lastName;
}
}

public event PropertyChangedEventHandler PropertyChanged;

private void RaisePropertyChanged(string property)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
}
}

 

ViewModel

En la capa intermedia ViewModel añadimos la clase StudentViewModel.cs. La clase representa el origen de datos de donde se nutre con la lista de alumnos.

La clase StudentViewModel contiene un solo atributo público de tipo Clase ObservableCollection<T>  esta clase representa una colección de datos dinámicos de la clase Student definida en el modelo de datos. El método público LoadStudents() carga la colección de datos con la información de los estudiantes.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using MVVMBasicDemo1.Model;
using System.Collections.ObjectModel;

namespace MVVMBasicDemo1.ViewModel
{
class StudentViewModel
{
public ObservableCollection<Student> Students
{
get;
set;
}

public void LoadStudents()
{
ObservableCollection<Student> students = new ObservableCollection<Student>();

students.Add(new Student { FirstName = "Mark", LastName = "Allain" });
students.Add(new Student { FirstName = "Allen", LastName = "Brown" });
students.Add(new Student { FirstName = "Linda", LastName = "Hamerski" });
students.Add(new Student { FirstName = "Iker", LastName = "Landajuela" });

Students = students;
}
}
}

Views

Lo primero hemos movido el archivo MainWindow.xaml a la carpeta Views donde debería estar.

App.xaml es el punto de entrada cuando arranca la aplicación, VS lo genera de forma automática cuando creamos el proyecto de tipo WPF.

En este fichero debemos modificar el atributo StartupUri para que apunte a  MainWindow.xaml dentro de la carpeta Views. Si quisiéramos mostrar otra ventana en el inicio de la aplicación la definimos en este campo.

App.xaml incluye también por detrás código en el fichero App.xaml.cs (clase Application).

 

MainWindow.xaml

Este fichero contiene la definición de la ventana de nuestra aplicación usando XAML y la etiqueta Window. Definimos algunas propiedades básicas como el tamaño de ventana y el título.

Dentro de Window definimos un control Grid, este control define una rejilla donde alojamos controles en las casillas (Ver The Grid Control). En nuestro caso sólo contiene una vista con la etiqueta views que se encarga de cargar nuestra vista StudentView.xaml.

StudentView.xaml

He añadido un nuevo elemento de tipo “User Control (WPF)” al proyecto en la carpeta Views.  El archivo StudentView.xaml contiene los controles para visualizar la lista de estudiantes, la etiqueta principal UserControl contiene un Grid, dentro un control StackPanel (Ver “WPF StackPanel“).

El control ItemsControl es donde opera la magia del data-binding, se asocia a la propiedad Students (colección de clases Student) definida en la clase StudentViewModel. Dentro de ItemsControl se define ItemsControl.ItemTemplate que contiene el modelo de visualización de un estudiante.

Cada clase TextBox se asocia a un atributo de la clase student usando la propiedad Text.


<UserControl x:Class = "MVVMBasicDemo1.Views.StudentView"
xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d = "http://schemas.microsoft.com/expression/blend/2008"
xmlns:local = "clr-namespace:MVVMBasicDemo1.Views"
mc:Ignorable = "d"
d:DesignHeight = "300" d:DesignWidth = "300">

<Grid>
<StackPanel HorizontalAlignment = "Left">

<ItemsControl ItemsSource = "{Binding Path = Students}">

<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation = "Horizontal">
<TextBox Text = "{Binding Path = FirstName, Mode = TwoWay}"
Width = "100" Margin = "3 5 3 5"/>

<TextBox Text = "{Binding Path = LastName, Mode = TwoWay}"
Width = "100" Margin = "0 5 3 5"/>

<TextBlock Text = "{Binding Path = FullName, Mode = OneWay}"
Margin = "0 5 3 5"/>

</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>

</ItemsControl>

</StackPanel>
</Grid>

</UserControl>

 

Enlaces externos

Anuncios

Layout: Aplicación en línea para crear diseños Web

layoutit21

lay1Con layoutit podemos crear elegantes diseños Web sin tener muchos conocimientos de CSS, JS o HTML. La aplicación en línea y gratuita para proyectos públicos facilita crear un diseño arrastrando y soltando elementos como: formularios, cabeceras, elementos JS como un carrusel de fotos, etc,.

Os dejo el enlace a un diseño que estoy realizando para probar la aplicación:  http://bit.ly/1l5TDIk

Hasta el momento todo va bien, después de un rato trabajando he decidido bajarme el código generado (en formato .zip con la estructura de carpetas), ahora que ya tengo la maquetación básica.

Bueno subo a Google Drive lo que he hecho hasta el momento (tengo que comprar comida para sobrevivir en la cueva del programador).

Diseño Web adaptativo con CSS3 media queries

Introducción

responsive_design

Las media queries es el pilar básico del diseño web adaptativo (Responsive Web Design o RWD ) ,  gracias a las media queries en CSS3 podemos detectar las características del dispositivo, por ejemplo la resolución de la pantalla, que es el caso que nos ocupa hoy.

DEMO: Una pequeña demo, cuando redimensionamos la pantalla cambia la disposición de los apartados, desaparece el texto explicativo de cada apartado.

Con los media queries dependiendo del dispositivo que usemos podemos modificar el aspecto y la disposición de los elementos de nuestra página, por ejemplo en la imagen inferior podemos ver como los elementos cambian de posición dependiendo si empleamos un ordenador de escritorio o un dispositivo como una tablet o un teléfono móvil.

media-queries-desktop-ipad-iphone

Con los media queries nos ahorramos rediseñar una web desde cero para cada dispositivo (que redunda en costes de desarrollo y sobre todo de mantenimiento) .

Un ejemplo de algunas webs de éxito que emplean el RWD como el Time. Empleando Firefox tenemos una herramienta para desarrolladores para ver una web en diferentes resoluciones (el método más rápido y el clásico es redimensionar la propia pantalla del navegador) , cuando optamos por un tamaño como el de una pantalla de móvil se producen algunos cambios, el menú principal se esconde como desplegable bajo “SECTIONS”, las noticias principales se colocan en una columna vertical, los iconos sociales también desaparecen, etc…

rwd_1

Vista en pantalla PC Escritorio

rwd_2

Vista a una resolución de 369×640

Manos a la obra

La sintaxis aproximada de una media querie es la siguiente (si la declaramos dentro de un documento):

@media screen and (min-width:500px) { ... }

En este ejemplo dentro de esta regla codificaremos los aspectos particulares de diseño para una pantalla con una anchura mínima de 500 pixel.

Podemos definir por ejemplo media queries que cumplan más de una condición, por ejemplo:

@media screen and (min-width:768px) and (max-width:1024px){ ... }

Ahora viene la pregunta del millón: ¿Cuantas medias queries vamos a definir y para que anchuras? Teniendo en cuenta esto ¿A que dimensiones queremos que se produzcan esos cambios significativos de diseño (breakpoints)? No se si hay respuesta correcta (depende del artículo que consultes) en cualquier caso siempre se debe tener en mente que hábitos tienen los usuarios a los que va destinada nuestra web a la hora de navegar por la basta red de redes.

Si sois de los que no os apetece romperos el coco con este tema, tan sencillo como realizar búsquedas en internet del tipo “estandar media queries”  o hacer un copia pega de CSS Tricks : “Media Queries for Standard Devices” o de “CSS Media Queries For Common Devices“.

Una buena idea también puede ser definir 3 o 4 media queries genéricos: Una para móviles, otra para  tablets y por último otra para pantallas de escritorio (4 si añadimos la vista horizontal, pantalla de una tablet girada).

  • …(max-width:1070px){…} (PC)
  • …(max-width:800px){…} (tablet)
  • …(max-width:570px){…} (landscape)
  • …(max-width:450px){…} (portrait)

Algunos expertos como Luke Wroblewski ya llevan tiempo devanándose el seso  con estas cuestiones, en su web pública un artículo muy interesante “Multi-Device Layout Patterns” donde establece unos modelos RWD basandose en patrones que se repiten en los diseños.

md-patterns1

El patrón más popular según Luke.

+INFO:

Artículos relacionados:

https://ikerlandajuela.wordpress.com/2013/10/29/diseno-web-adaptativo-de-imagenes-con-picturefill/