[Windows 8] Apps Metro para desarrolladores Windows Phone 7.5 (1 de N)

Hola a todos!

Hoy vamos a cambiar un poco la temática del blog, para hablar de Windows 8 y más concretamente de las aplicaciones Metro. Vamos a dar un vistazo a las similitudes y diferencias que encontraremos en este tipo de aplicaciones desde el punto de vista de un desarrollador Windows Phone.

Una de las cosas que nos sorprenderá cuando empecemos a trabajar con Windows 8 y sus aplicaciones Metro, será el gran número de similitudes que encontraremos con la plataforma Windows Phone. Aunque sutiles, también encontraremos diferencias en el desarrollo, pero son fáciles de comprender y acostumbrarnos a ellas es más fácil todavía. Vamos a comenzar por los cimientos.

Unos buenos cimientos: MVVM

Una de las cosas que no ha cambiado en Windows 8 es la forma de aplicar el patrón MVVM en nuestra aplicación. Podemos coger la estructura de una aplicación Windows Phone y trasladarla fácilmente a Windows 8. Las expresiones de enlace a datos siguen funcionando como siempre lo han  hecho y podemos establecer nuestra ViewModel como DataContext de una página.

En Windows Phone es muy normal usar una viewmodel base, que implemente INotifyPropertyChanged y para las colecciones apoyarnos en ObservableCollection<T>.

En la versión developer preview de Win8 esto nos podía dar algún dolor de cabeza (mira este artículo de Eduard Tomas) pues existían dos implementaciones de INotifyPropertyChanged: la de siempre, que se encuentra en System.ComponentModel y la nueva implementación en WinRT que se encontraba en Windows.UI.Xaml.Data Esto hacía que los cambios no se notificasen correctamente. Pero parece que en la nueva versión Consumer preview se han unificado de nuevo, manteniéndose en System.ComponentModel, y desapareciendo de Windows.UI.Xaml.Data.

De esta forma, podemos crear una ViewModel base realmente sencilla y totalmente intercambiable entre Windows Phone y Windows 8:

VMBase
  1. using System.ComponentModel;
  2.  
  3. namespace Geeks.ms.ViewModels.Base
  4. {
  5.     public class VMBase : INotifyPropertyChanged
  6.     {
  7.         public VMBase()
  8.         {
  9.         }
  10.  
  11.         public event PropertyChangedEventHandler PropertyChanged;
  12.  
  13.         public void RaiseChange(string name)
  14.         {
  15.             if (PropertyChanged != null)
  16.                 PropertyChanged(this, new PropertyChangedEventArgs(name));
  17.         }
  18.     }
  19. }

Navegación

El mayor cambio que encontraremos al implementar MVVM se centrará fundamentalmente en la forma de navegar entre las páginas de nuestra aplicación. En Windows Phone, una clase normal de navegación que pudiese ser usada desde cualquier ViewModel simplemente tenía que obtener el contener principal de la aplicación, expuesto a través de la propiedad RootVisual del objeto App:

Navegación en Windows Phone
  1. public void NavigateTo(String navigationTarget)
  2. {
  3.     PhoneApplicationFrame rootFrame = Application.Current.RootVisual as PhoneApplicationFrame;
  4.     rootFrame.Navigate(registeredViews[navigationTarget]);
  5. }

En Windows 8 no disponemos de la propiedad RootVisual. Al inicializar la aplicación se crea un objeto Frame que es el encargado de gestionar la navegación. Lo que necesitamos para poder crear un servicio de navegación básico es crear una propiedad estática en nuestra clase App que nos devuelva este Frame principal:

RootFrame
  1. sealed partial class App : Application
  2. {
  3.     /// <summary>
  4.     /// Application main frame, used for navigation
  5.     /// </summary>
  6.     public static Frame RootFrame = new Frame();

En el evento OnLaunched usaremos este RootFrame para navegar a nuestra página inicial y lo estableceremos como el contenido de nuestra ventana:

Evento OnLaunched
  1. protected override void OnLaunched(LaunchActivatedEventArgs args)
  2. {
  3.     if (args.PreviousExecutionState == ApplicationExecutionState.Terminated)
  4.     {
  5.     }
  6.  
  7.     // Create a Frame to act navigation context and navigate to the first page
  8.  
  9.     RootFrame.Navigate(typeof(BlankPage));
  10.  
  11.     // Place the frame in the current Window and ensure that it is active
  12.     Window.Current.Content = RootFrame;
  13.     Window.Current.Activate();
  14. }

Ahora solo nos queda obtener una referencia a este Frame principal en nuestra clase de navegación y usarlo en nuestros métodos:

Clase NavigationService
  1. using System;
  2. using Geeks.ms.Views;
  3. using Windows.UI.Xaml.Controls;
  4.  
  5. namespace Geeks.ms.Services.Navigation
  6. {
  7.     public class NavigationService : INavigationService
  8.     {
  9.         private readonly Frame frame;
  10.  
  11.         public NavigationService()
  12.         {
  13.             frame = App.RootFrame;
  14.         }
  15.  
  16.         public void NavigateBack()
  17.         {
  18.             frame.GoBack();
  19.         }
  20.  
  21.         public bool CanNavigateBack()
  22.         {
  23.             return frame.CanGoBack;
  24.         }
  25.  
  26.         public void NavigateToArticle(Uri articleUri)
  27.         {
  28.             frame.Navigate(typeof(VArticle), articleUri);
  29.         }
  30.     }
  31. }

Y ya podremos invocar a esta clase desde nuestras ViewModel. Otro punto de la navegación que cambia con respecto a Windows Phone es la cache de las páginas visitadas. En Windows Phone si llamábamos al método GoBack del NavigationService, automáticamente volvíamos a la página anterior, que se conservaba en el estado en el que la habíamos dejado.

En Windows 8 esto cambia, por defecto las instancias de las páginas no se conservan, la pila de navegación solo conoce el tipo y cuando hacemos un GoBack (o un GoForward, que sí está soportado en Windows 8 y nos ahorrará problemas de navegación circular) simplemente se crea una nueva instancia de la página anterior, perdiendo el estado que tenía. Este comportamiento puede ser modificado mediante la propiedad NavigationCacheMode presente en la clase Page:

Cabecera de una página Xaml
  1. <Page
  2.     x:Class="Geeks.ms.BlankPage"
  3.     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  4.     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  5.     xmlns:local="using:Geeks.ms"
  6.     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  7.     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  8.     mc:Ignorable="d"
  9.     NavigationCacheMode="Enabled"
  10.     DataContext="{Binding Path=StartPage, Source={StaticResource VmLocator}}">

La propiedad NavigationCacheMode puede tener tres valores:

  1. Enabled: La instancia se conserva en memoria, siempre y cuando no superemos el número de páginas máximo que hayamos establecido en nuestro Frame principal.
  2. Required: La instancia de esta página no cuenta en el total de páginas indicado en el Frame principal, simplemente debe ser conservada y no será destruida aunque se supere el máximo.
  3. Disabled: Este es el valor por defecto, se crea una nueva instancia por cada visita.

Por defecto, el objeto Frame establece la propiedad CacheSize con un tamaño de 10 páginas, aunque podemos modificarlo simplemente estableciendo la propiedad CacheSize de nuestro RootFrame:

CacheSize
  1. RootFrame.CacheSize = 12;

Algo que debemos tener en cuenta es que, si marcamos la propiedad NavigationCacheMode como Enabled o Required, si al navegar a una página se encuentra su instancia en memoria, se usará esta instancia. Si tenemos una página cuyo contenido cambiará cada vez que accedamos a ella, lo mejor es no habilitar el cache, pues no lo necesitamos.

Algo sobre lo que todavía estoy investigando y realizando pruebas es todo lo relacionado al IoC, en cuanto haya revisado todas las opciones que hay, os contaré mis ideas finales!.

Conclusión

Esto ha sido una breve introducción a las aplicaciones Metro en C#, desde el punto de vista de un desarrollador Windows Phone. En el próximo artículo veremos más detalles sobre Expression Blend 5, un poco de Async, el emulador de Windows 8 y un ejemplo de aplicación metro, así que empezad a descargar Windows 8 y Visual Studio 11 si no lo tenéis ya, es realmente divertido y vale la pena ponerle las manos encima cuanto antes.

Un saludo y Happy Coding!

Published 2/4/2012 5:46 por Josué Yeray Julián Ferreiro
Archivado en: ,,
Comparte este post:

Comentarios

# re: [Windows 8] Apps Metro para desarrolladores Windows Phone 7.5 (1 de N)

Tuesday, April 3, 2012 3:14 PM por Eduard Tomàs i Avellana

Genial artículo Josué!

Personalmente opino que es una pena que el modelo de desarrollo entre WP7 y W8 sea tan parecido pero sea distino: debería ser el mismo.

Eso me plantea dudas sobre el futuro de los desarrollos para WP7: Seguirán siendo en SL dentro de, pongamos año y pico? Deberemos mantener dos codebases distintos para W8 y WP7? Si en W8 decidieron que Silverlight NO era la tecnología apropiada para desarrollar en Metro... la seguirán manteniendo en WPx?

En fin... veremos :)

Un abrazo monstruo!

PD: Gracias x la referencia!

# re: [Windows 8] Apps Metro para desarrolladores Windows Phone 7.5 (1 de N)

Tuesday, April 3, 2012 3:35 PM por Josué Yeray Julián Ferreiro

Buenas Eduard!

La verdad es que estaría genial saber que nos depara WinPhone en el futuro. Lo que está claro es que el modelo Metro de Win8 es muy divertido para desarrollar y muuuy potente :)

Un abrazo señor!

# [Windows 8] Apps Metro para desarrolladores Windows Phone 7.5 (2 de N)

Thursday, April 5, 2012 1:20 PM por Josue Yeray

Hola a todos! En el primer artículo de esta serie pudimos ver como la implementación del

# Navigator para WP7 en MVVM

Sunday, August 5, 2012 11:41 AM por Omar del Valle Rodríguez

Otro tema que estaba pendiente... Cuando empecé a estudiar y testear cosas de WP7 con MVVM, una de los