[Universal App] Uso del Zoom Semantico, creando Jumplists

JumpListIntroducción

Estas envuelto en el desarrollo de una aplicación universal y quieres utilizar un control jumplist, un listado con organizado en grupos que además nos permiten acceder rapidamente a elementos de otros grupos. Si ya has desarrollado previamente para Windows Phone habrás intentando utilizar un contorl LongListSelector pero… ¿que ocurre?, ¿dónde se encuentra?. Las aplicaciones universales tanto Windows como Windows Phone funcionan bajo WinRT donde no tenemos disponible el control. Pero esperad, tranquilos, con la unificación de las plataformas el control LongListSelector de Windows Phone 8 pasa a ser reemplazado por el zoom semántico que ya teníamos en las aplicaciones Windows Store. En este artículo vamos a crear un proyecto universal desde cero y a utilizar en una aplicación el control SemanticZoom para ver como reemplaza al LongListSelecto ren Windows Phone y su uso en Windows Store.

¿Te apuntas?

¿Qué es el Zoom Semántico?

En zoom semántico es la forma que podemos utilizar en nuestras aplicaciones universales a la hora de presentar conjuntos grandes de datos o datos relacionados entre si en una única vista. El control SemanticZoom nos permite mostrar la información al usuario en dos vistas distintas del mismo contenido.

Para hacer zoom semántico, podemos hacerlo mediante un simple gesto (acercando ambos dedos alejamos el zoom, alejando los dedos lo acercamos). Además en Windows podemos pulsar la tecla CTRL del teclado mientras hacemos scroll con el ratón (o pulsamos las teclas + o -).

Veamos un simple ejemplo para dejarlo todo más claro. Imaginaos que estamos desarrollando una aplicación de mensajería. Estamos viendo el historial de mensajes que se ha mantenido con un usuario en concreto. Veremos la vista reducida o alejada:

Vista reducida

Vista reducida

Si queremos tener de un simple vistazo todos los periodos de fechas en los que hemos mantenido mensajes con el usuario bastará con hacer hacer el gesto de acercar los dedos para mostrar la vista ampliada (tras una pequeña animación):

Vista ampliada

Vista ampliada

Como podéis ver en el ejemplo, sin necesidad de hacer scroll podemos mostrar de una simple vistazo la información deseada. Es más, tenemos la posibilidad de añadir información extra. En nuestro ejemplo además de mostrar los distintos periodos en los que se han mantenido conversaciones, se muestra el número de mensajes que se han realizados en cada uno de ellos.

Manos a la obra!

Vamos a crear una aplicación simple que muestre una colección de películas agrupadas por año. El objetivo final será añadir el uso del SemanticZoom para mostrar por defecto la colección de películas y al hacer el zoom out mostrar los distintos años en los que están agrupadas las películas.

Como siempre solemos hacer vamos a realizar un ejemplo lo más simple posible pero que nos sea válida para lograr nuestros objetivos:

Nueva aplicación universal

Nueva aplicación universal

Añadimos las carpetas Views, ViewModels y Services además de las clases base necesarias para implementar el patrón MVVM de la misma forma que vimos en este artículo. Para probar el control necesitamos una fuente de información. En nuestro ejemplo simplificaremos el proceso al máximo construyendo una colección de elementos en memoria.

Comenzamos creando el modelo de nuestra aplicación:

public class Movie
{
     public string Title { get; set; }

     public string Description { get; set; }

     public string Image { get; set; }

     public int Year { get; set; }
}

Para simplificar el ejemplo, no vamos a conectar nuestra aplicación con internet (rss, servicio web, azure, etc) sino que trabajaremos con datos estáticos. Para ello, en el constructor de nuestra viewmodel creamos un listado de películas:

var movies = new List<Movie>
{    
     new Movie {Title = "John Carter", Year = 2012, Image = "ms-appx:///Assets/Carter.jpg"},
     new Movie {Title = "El caballero oscuro: La leyenda renace", Year = 2012, Image = "ms-appx:///Assets/Batman.jpg"},
     new Movie {Title = "Cisne Negro", Year = 2011, Image = "ms-appx:///Assets/Cisne.jpg"},
     new Movie {Title = "Drive", Year = 2011, Image = "ms-appx:///Assets/Drive.jpg"},
     new Movie {Title = "Toy Story 3", Year = 2010, Image = "ms-appx:///Assets/Toy.jpg"},
     new Movie {Title = "El discurso del rey", Year = 2010, Image = "ms-appx:///Assets/Rey.jpg"},
     new Movie {Title = "Origen", Year = 2010, Image = "ms-appx:///Assets/Origen.jpg"},    
     new Movie {Title = "Avatar", Year = 2009, Image = "ms-appx:///Assets/Avatar.jpg"}
};

NOTA: Las imágenes utilizadas son recursos locales compartidos en una carpeta llamada Assets del proyecto Shared.

Llegamos a este punto podríamos crear una propiedad pública para poder hacer binding (enlazar) desde nuestra interfaz con la colección creada. Sin embargo, dentro de nuestros objetivos está el mostrar la colección de películas agrupadas por año. Además, con el control SemanticZoom queremos mostrar el listado de grupos (años) distintos que contienen películas. Debemos agrupar nuestra colección antes de continuar. Para ello, dentro de nuestra carpeta “Models” anteriormente creada vamos a añadir una nueva clase:

public class MoviesByYear
{
     public int Year { get; set; }
    public List<Movie> Movies { get; set; }
}

Es simple. Almacenará un año junto a la colección de películas de dicho año correspondientes. Tenemos ya donde almacenar la información, vamos a hacerlo.

var moviesByYear = movies.GroupBy(f => f.Year).Select(f => new MoviesByYear { Year = f.Key, Movies = f.ToList() });

Ahora si, creamos una propiedad pública que contendrá la colección de películas agrupadas por año:

public List<MoviesByYear> Movies
{
     get { return _movies; }
     set { _movies = value; }
}

Hemos dejado el view model totalmente preparado. Llega el momento de centrarnos en la vista. Vamos a añadir nuestro control SemanticZoom a nuestra vista MainView:

<SemanticZoom>
     <SemanticZoom.ZoomedInView>

     </SemanticZoom.ZoomedInView>
     <SemanticZoom.ZoomedOutView>

     </SemanticZoom.ZoomedOutView>
</SemanticZoom>

La estructura que puedes ver en la parte superior es la estructura básica a utilizar en un control SemanticZoom. Como puedes observar el control contendrá otros dos controles (normalmente listas). El primero de los controles se añadirá en la vista ZoomedOutview, vista mostrada por defecto. El segundo, se añadirá a la vista ZoomedInView. Vista que mostramos al hacer Zoom Semántico. Ambas vistas están relacionadas semánticamente.

Antes de continuar, veamos algunos miembros importantes del control:

Propiedades

  • ZoomedInView. Vista Zoomed-In del control SemanticZoom.
  • ZoomedOutView. Vista Zoomed-Out del control SemanticZoom.
  • CanChangesView. Determina si el control permite cambiar de vista (Propiedad de sólo lectura).
  • IsZoomedInViewActive. Propiedad de tipo bool nos permite definir con que vista se muestra el control SemanticZoom (ZoomIn o ZoomOut).

Eventos

  • ViewChangeStarted. Se lanza al comenzar el cambio de una vista.
  • ViewChangedCompleted. Se lanza al completarse el cambio de una vista (la nueva vista se muestra).
<SemanticZoom>
     <SemanticZoom.ZoomedInView>
          <ListView>
          </ListView>
     </SemanticZoom.ZoomedInView>
     <SemanticZoom.ZoomedOutView>
          <GridView />
     </SemanticZoom.ZoomedOutView>
</SemanticZoom>

Añadiremos en los recursos de la página un CollectionViewSource que hará binding con nuestra propiedad pública Movies creada en la viewmodel:

<CollectionViewSource
            x:Name="groupedMoviesViewSource"
            Source="{Binding Movies}"
            IsSourceGrouped="true"
            ItemsPath="Movies"/>

Pasamos a definir los DataTemplates:

<DataTemplate x:Key="MovieJumpTemplate">
     <Border Padding="5">
          <Border Background="{Binding Converter={StaticResource BackgroundConverter}}"
                  Width="82" Height="82" HorizontalAlignment="Left">
                <TextBlock Text="{Binding Group.Year}"
                           Foreground="{Binding Converter={StaticResource ForegroundConverter}}"
                           FontSize="24" Padding="6"
                           HorizontalAlignment="Center" VerticalAlignment="Center"/>
          </Border>
     </Border>
</DataTemplate>

<DataTemplate x:Key="MovieItemTemplate">
     <Grid>
          <Grid.ColumnDefinitions>
               <ColumnDefinition Width="Auto"/>
               <ColumnDefinition Width="*"/>
          </Grid.ColumnDefinitions>
          <Image Source="{Binding Image}" Stretch="Uniform" MaxWidth="100"
                 Margin="0, 5"/>
          <TextBlock Grid.Column="1" FontSize="32"
                     Text="{Binding Title}" TextWrapping="WrapWholeWords"
                     Margin="5" />
     </Grid>
</DataTemplate>

<DataTemplate x:Key="MovieGroupHeaderTemplate">
     <Border Background="Transparent" Padding="5">
          <TextBlock Text="{Binding Year}" Foreground="{StaticResource PhoneForegroundBrush}" FontSize="32" Padding="6"
                       FontFamily="{StaticResource PhoneFontFamilySemiLight}" HorizontalAlignment="Left" VerticalAlignment="Center"/>
     </Border>
</DataTemplate>

Necesitamos varias plantillas, en nuestro ejemplo:

  • MovieJumpTemplate: Cada uno de los elementos mostrados en la vista ZoomedOutView del zoom semántico.
  • MovieItemTemplate: Elementos básicos del listado mostrados en la vista por defecto.
  • MovieGroupHeaderTemplate: Cabecera de cada grupo mostrado en la lista por defecto.

NOTA: Creamos una carpeta Themes específica para clada plataforma, en los proyectos Windows y Windows Phone. Aqui añadiremos recursos de diccionarios donde agruparemos los estilos y plantillas específicar a usar en cada plataforma.

Finalmente nuestro zoom semántico quedaría:

<SemanticZoom>
     <SemanticZoom.ZoomedInView>
          <ListView
               IsHoldingEnabled="True"
               ItemsSource="{Binding Source={StaticResource groupedMoviesViewSource}}"
               ItemTemplate="{StaticResource MovieItemTemplate}">
               <ListView.GroupStyle>
                    <GroupStyle HidesIfEmpty="True"
                                HeaderTemplate="{StaticResource MovieGroupHeaderTemplate}">
                    </GroupStyle>
               </ListView.GroupStyle>
          </ListView>
     </SemanticZoom.ZoomedInView>
     <SemanticZoom.ZoomedOutView>
          <GridView ItemsSource="{Binding Source={StaticResource groupedMoviesViewSource}, Path=CollectionGroups}"
                    ItemTemplate="{StaticResource MovieJumpTemplate}"/>
     </SemanticZoom.ZoomedOutView>
</SemanticZoom>

Analicemos el código anterior:

  • Ya hemos visto el funcionamiento del zoom semántico además de conocer sus dos vistas, ZoomedInView y ZoomedOuView.
  • En la vista por defecto mostramos un control ListView. Este control nos permite organizar los elementos en grupos utilizando la propiedad GroupStyle. La apariencia de cada cabecera vendrá definido por la plantilla indicada en la propiedad HeaderTemplate y podemos ocultar cabeceras sin contenido gracias a la propiedad HidesIfEmpty.
  • El JumpList lo conseguimos utilizando el ListView con sus grupos junto al zoom semántico.
  • En la vista ZoomOutView mostramos un GridView bindeado a la misma fuente de información que el ListView, el CollectionViewSource pero accediendo a la propiedad CollectionGroups de la vista que contiene la colección de grupos.

El resultado del ejemplo es el siguiente:

Vista reducida en Windows Phone

Vista reducida en Windows Phone

Podemos ver el listado de películas agrupadas por año (vista ZoomInView), mostrando el año como cabecera. Al pulsar sobre cualquiera de los años:

Vista ampliada en Windows Phone

Vista ampliada en Windows Phone

Pasamos a la vista ZoomOutView viendo todos los años disponibles. La aplicación Windows Store mostrará un resultado similar:

Vista reducida en Windows

Vista reducida en Windows

Mediante un simple gesto (acercando ambos dedos alejamos el zoom, alejando los dedos lo acercamos) o pulsando la tecla CTRL del teclado mientras hacemos scroll con el ratón (o pulsamos las teclas + o -) pasamos a la vista ZoomOutView:

Vista ampliada en Windows

Vista ampliada en Windows

En la vista ZoomOutView vemos el listado de años mostrando además información extra, en este caso el número de películas disponibles en cada año.

Puedes descargar el ejemplo realizado:

Espero que lo visto en la entrada os resulte interesante. Recordar, cualquier duda o sugerencia será bienvenida en los comentarios de la entrada.

Conclusiones

  • El control SemanticZoom forma parte del conjunto de controles WinRT compartido entre Windows y Windows Phone.
  • A pesar de tener el control compartido entre ambas plataformas, en cada una de ellas se adapta para otorgar la experiencia adecuada.
  • El control nos permite trabajar con dos vistas distintas a la hora de mostrar colecciones con un número elevado de elementos. Evita scrolls muy largos, facilita la navegación e interacción entre los elementos.
  • ZoomedInView es la vista por defecto que muestra el Zoom Semántico.
  • ZoomedOutView es la vista mostrada al hacer Zoom Semántico.
  • Para poder utilizar un control en alguna de las vistas del SemanticZoom debe implementar la interfaz ISemanticZoomInfo.
  • Por defecto los controles que heredan de ListViewBase implementan la interfaz ISemanticZoomInfo.
  • CUIDADO: Con el uso del control Listbox que no hereda de ListViewBase y por lo tanto NO implementa ISemanticZoomInfo. No se puede utilizar un control Listbox en una de las vistas del control SemanticZoom.
  • Normalmente se muestra la colección de elementos en la vista ZoomedInView y los grupos de dicha colección en la vista ZoomedOutView. Por ello, también es normal que la fuente de datos del control sea un CollectionViewSource. Aunque no tiene porque ser siempre asi.
  • No tiene una propiedad ItemsSource. No hacemos Binding directamente a una colección de datos. El Binding se realiza desde los controles lista añadidos a cada una de las vistas del SemanticZoom.
  • Por supuesto, el contenido de las distintas vistas pueden hacer scroll.
  • No esta pensado para mostrar una colección y al pulsar sobre un elemento de la misma navegar a otra colección de detalles (Drill-Down). La información mostrada en ambas vistas es la misma.

Artículos relacionados

Más información

Novedades en la plataforma Windows a nivel de sistema

Introducción

Recientemente se celebro el //BUILD/, evento de Microsoft donde se presentaron nuevas versiones de la plataforma Windows para teléfonos, portátiles, tabletas y PCs. En este artículo hacemos un repaso general a las novedades más interesantes a nivel de usuario.

¿Te apuntas?

Novedades en Windows Phone 8.1

No nos debemos dejar engañar por la versión. Windows Phone 8.1 no es una versión menor a nivel de mejoras ni a nivel de sistema ni a nivel de desarrollo.

El listado de novedades es grande. A continuación podéis ver un video resumen con todas ellas:

Cortana. Asistente personal digital

No podía comenzar el listado de novedades en Windows Phone 8.1 por otro punto que no fuese… Cortana.

Inspirado por un famoso personaje de Halo que era un asistente digital personal para el protagonista del juego, Master Chief, nos llega un asistente de voz personal a Windows Phone.

NOTA: Tras la voz de Cortana esta Jen Taylor la misma mujer que dio voz al personaje en el videojuego.

Cortana

Cortana

En otras plataformas contaban con Siri (Apple) o Google Now (Google), asistentes de voz más versátiles que el sistema de reconocimiento de voz con el que contábamos hasta ahora en Windows Phone. Cortana llega para ir más alla que todo lo existente hasta ahora.

¿Cómo?

Cortana no se limitará a un sistema que reaccionará ante comandos de voz, si no que tomará múltiples fuentes para contar con la mayor cantidad de información posible para interaccionar de la forma más precisa posible.

La primera vez que usemos Cortana nos realizará algunas preguntas básicas sobre nosotros. A partir de ese momento, Cortana mirara en contactos, lugares habituales, intereses… todo lo necesario para aprender lo máximo posible de nosotros mismos.

NOTA: El nivel de acceso de Cortana a nuestros datos es configurable.

Asi que Cortana no se limita a responder órdenes o realizar búsquedas básicas como lugares, el tiempo o resultados deportivos, además puede establecer recordatorios como recordarle a tu madre que tal le va el nuevo Windows Phone que le has regalado por ejemplo.

Por si fuese poco, otra gran diferencia de Cortana con otros asistentes digitales es la posibilidad de interactuar con aplicaciones de terceros. Esto permite que Cortana pueda interactuar con miles de aplicaciones. Por ejemplo, en el //BUILD/ vimos como interactuaba con Twitter pudiéndole indicar un tweet o con Hulu pidiendole que te recuerde cuando sale el próximo capítulo de nuestra serie favorita.

Llegára en breve en fase beta y en la segunda mitad de este año llegará la versión oficial a EEUU, UK y China. Para otros paises tendremos que esperar aun mas.

Action Center

Los Live Tiles disponibles en la plataforma Windows son una excelente y elegante forma de notificar al usuario con información relevante para el mismo. Sin embargo, no todas las aplicaciones están ancladas al inicio y a veces el usuario puede perder información. Para solventar esto llega el Action Center, un lugar donde ver todas las notificaciones de todas las aplicaciones incluso de las no ancladas al incio además de poder acceder a configuración básica del sistema como el modo vuelo, WiFi o Bluetooth.

Action Center

Action Center

Start Screen

El año pasado con la llegada de los dispositivos de pantalla grande (5″ o superior) se habilito una tercera columna de tiles en la pantalla principal. Ahora con la llegada de Windows Phone 8.1 se habilita esta opción para todos los dispositivos Windows Phone 8.1 de cualquier tipo de pantalla.

Pantalla de inicio

Pantalla de inicio

Lock Screen

La pantalla de bloqueo ahora capta aun mas importancia permitiendo establecer distintos temas que aplican diferentes estilos visuales y animaciones.

LockScreen

LockScreen

Word Flow Keyboard

Nuevo teclado que aprende de nuestro estilo de escritura y accede a los nombres de las personas de la agenda para acelerar la escritura. Además, este nuevo teclado permite deslizar los dedos sobre las teclas para escribir de una forma mucho más rapida.

Word Flow Keyboard

Word Flow Keyboard

NOTA: El record de velocidad de escritura estaba registrado con el teclado Swype en un Samsung Galaxy S4 y ha sido batido por este teclado por 8 segundos.

Data Sense, Storage Sense, WiFi Sense y Battery Saver

Se han añadido un conjunto muy interesante de aplicaciones destinadas a recibir información relevante de que sucede en el sistema. Nivel de batería, estado de las redes, almacenamiento, etc.

  • Data Sense: Permite ver el cosumo de datos mensuales en total y por cada aplicación. Se puede además establecer límites para controlar los costes de nuestro plan de datos. En Windows Phone 8.1 además se incluye un modo de gran ahorro que comprime imágenes y datos del navegador permitiendo navegar consumiendo menos datos.
  • WiFi Sense: Nos permite conectar automáticamente con redes WiFi abiertas para ahorrar batería.
  • Storage Sense: Ayuda  a gestionar el contenido del almacenamiento del teléfono y de la tarjeta SD. Podemos mover contenido entre ambos almacenamientos.
  • Battery Saver: Indica como estan usando la batería las aplicaciones facilitandonos información útil para poder tomar decisiones al respecto. Cuenta con un modo automático que puede reducir considerablemente el uso de batería.

Calendario

La aplicación Calendario hasido rediseñado añadiendo una nueva vista semana (muy echada de menos y pedida) con soporte totala gestos táctil para la interacción.

Podcasts

Las secciones música, video y podcasts han sido divididas en distintas aplicaciones potenciando las capacidades de cada una de ellas.

Sector empresarial

Se han realizado grandes mejoras destinadas al mercado empresarial. Asi se ha añadido soporte a S/MIME, VPN, más políticas MDM, más opciones MDM, etc.

Otros

El listado de novedades es muy extenso, a continuación tenemos un listado de otras mejoras también importantes:

  • Tenemos mejoras en Skype, pudiendo pasar de una llamada ordinaria a una llamada Skype pulsando un simple botón; mejoras en la aplicación de correo electrónico, ahora con soporte a S/MIME emails y soporte a más tipos de cuentas como por ejemplo iCloud; se ha mejorado el Hub de contactos mejorando la integración con apps de terceros, la cámara y la aplicación de fotos permitiendo integración de aplicaciones de terceros para realizar tareas como albums online, diferentes formas de organización, etc.
  • Las apps podrán actualizarse de manera automática tal y como se puede hacer en Windows 8.1. Podremos ordenar las aplicaciones por fecha, por uso, etc.

Nuevos dispositivos

En breve y gracias al programa Developer Preview todos podremos actualizar nuestros dispositivos Windows Phone 8 a Windows Phone 8.1 pero… todo quedaría más “redondo” con nuevos dispositivos, ¿verdad?.

Nokia ha presentado varios teléfonos nuevos con Windows Phone 8.1.

Comenzamos por el nuevo buque insignia Windows Phone, el Nokia Lumia 930. Un terminal con 5″ FullHD, cuatro núcleos Qualcomm 2,2Ghz, 2GB de RAM, 32GB de almacenamiento y una cámara PureView de 20 megapixeles.

Nokia Lumia 930

Nokia Lumia 930

Llegará en Junio a un precio orientativo de 599 dólares.

Por otro lado se presentaron también los Nokia Lumia 630 y 635. Ambos con Windows Phone 8.1 , 4,5″ IPS, cuatro núcleos Snapdragon 400 1,2Ghz, 512MB de RAM y cámara de 5 megapixeles.

NOTA: El Lumia 630 llega en dos versiones, con y sin dual SIM. El Lumia 635 incluye LTE.

Los dos llegarán en unos meses por debajo de los 200 dólares (159$ el Lumia 630, 169$ el Lumia 630 Dual SIM y 189$ el Lumia 635).

Novedades en Windows 8.1

Las novedades de la actualización de Windows 8.1 se centran en otorgar una experiencia de usuario mejor adaptada a los usuarios de teclado y ratón además de facilitar el acceso a desarrolladores y permitir a los fabricantes crear nuevos dispositivos de costes más bajos.

Mayor facilidad de uso con teclado y ratón

Ahora, usando teclado y ratón, al mover el cursor del ratón a la parte superior de la pantalla en una aplicación Windows Store veremos algo “familiar”, los botones minimizar y cerrar:

Minimizar y cerrar aplicaciones Windows Store

Minimizar y cerrar aplicaciones Windows Store

En la pantalla principal haciendo clic dereho sobre un Tile nos aparecerá un menu contextual que nos permitirá anclar a la barra de tareas, cambiar el tamaño, desanclar de la pantalla de inicio o desinstalar la aplicación entre otras opciones.

Se facilita el acceso a aplicaciones y a acciones del sistema

En la pantalla de inicio, en la aprte superior derecha al lado del usuario se han añadido unos botones de acceso rápido para apagar el sistema o para realizar búsquedas con una mayor rapidez.

Botón de apagado y búsqueda

Botón de apagado y búsqueda

También podemos acceder ahora directamente si lo deseamos al escritorio clásico.

Mayor facilidad para encontrar aplicaciones

Tras instalar la actualización nos encontraremos la Store anclada a la barra de tareas. De esta forma tendremos un acceso más sencillo y rápido a la tienda para encontrar nuevas aplicaciones.

Store anclada en la barra de tareas

Store anclada en la barra de tareas

Además en la parte inferior izquierda (donde podemos acceder a todas las aplicaciones instaladas) nos aparecerá un mensaje cada vez que tengamos nuevas aplicaciones recien instaladas.

Llegarán dispositivos de costes más bajos

Con la llegada del Update 1 se habilita la opción de crear dispositivos con solo 1GB de RAM y 16GB de almacenamiento a fabricantes.

Más información

[Windows 8.1] Introducción al control Hub

W8.1_LogoIntroducción

Recientemente se han presentado con grandes novedades para los desarrolladores .NET en el marco del //BUILD 2013. Se ha liberado Windows 8.1 y con el han llegado una gran variedad de novedades de cara a los desarrolladores. Entre las novedades recibidas tenemos un listado interesante de nuevos controles. El listado de nuevos controles es el siguiente:

  • AppBar controls
  • CommandBar
  • DatePicker
  • Flyout
  • Hub
  • Hyperlink
  • MenuFlyout
  • SettingsFlyout
  • TimePicker

De entre todos uno de los más interesantes ya que se utiliza como estructura base sobre la que crear la aplicación podemos destacar al control Hub.

El control Hub como ya hemos mencionado nos permite definir la estructura base de nuestra aplicación (tal y como nos lo permitía el control GridView por ejemplo). Nos permite estructuar la información en secciones donde lo más importante y atractivo visualmente se colocará a la izquierda mientras que el resto de opciones donde se profundiza más en la información se situa más a la derecha. El usuario accede a la información extra haciendo scroll horizontal. El objetivo del control es permitir mostrar la información con el mayor atractivo visual posible para atraer al usuario a descubrirla. Con respecto al GridView contamos con ventajas como:

  • No tenemos que enlazar al control a una colección de elementos. Podemos crear secciones con contenido y controles dispares en cada una de ellas.
  • Mayor capacidad de personalización.

Un ejemplo sencillo y reconocible de uso del control Hub lo podéis encontrar en la aplicación del tiempo:

El tiempo

El tiempo

Pinta bien, ¿te apuntas?

Arrancamos!

Abrimos Visual Studio 2013 Preview y creamos un nuevo proyecto. Dentro de la sección “Tienda Windows” contamos con las plantillas para crear aplicaciones Windows Store. Si nos fijamos contamos con novedades como por ejemplo la plantilla “Aplicación Hub” que nos crea la estructura de la aplicación utilizando el control Hub para ello. Podríamos utilizar la plantilla sin embargo para hacer el ejemplo lo más sencillo posible vamos a partir de una aplicación vacía:

Hub Template

Hub Template

Nos centramos en la vista principal (MainPage.xaml) donde vamos a añadir el control Hub. Partimos de lo más básico:

<Hub/>

No hay que agregar ni librerías ni namespaces. Recordar que es un nuevo control del SDK. Para desarrollar un poco el ejemplo vamos a simular la creación de una aplicación sobre la nueva Xbox. Continuamos estableciendo la propiedad básica, el título:

<Hub Header="Xbox One">
</Hub>

Fácil, ¿verdad?. El resultado hasta ahora sería algo asi:

Título del Hub

Título del Hub

El título en el control Hub siempre estará visible incluso cuando el usuario realice scroll horizontal sobre el contenido. El contenido del título puede ser tan simple como la cadena anterior o podemos requerir un contenido de mayor peso como imágenes o el botón volver por ejemplo. Podemos utilizar la propiedad Header para definir un contenido más complejo:

<Hub>
     <Hub.Header>
          <Grid>
          </Grid>
     </Hub.Header>
</Hub>

Añadiendo secciones

El control Hub se compone de secciones de tipo HubSection. El usuario accede a las secciones realizando scroll horizontal. En nuestro ejemplo sobre la Xbox One añadiremos tres secciones:

  • Primera sección: Mostrará una imágen sobre la consola junto a un titular.
  • Segunda sección: Descripción de la consola. Utilizaremos el control RichTextBox junto al nuevo control Hiperlink.
  • Tercera sección: Mostraremos el listado de juegos en el ya conocido control GridView.

Suena bien, ¿cierto?. Manos a la obra!

Vamos a definir la estructura base de secciones que sería algo como lo siguiente:

<Hub Header="Xbox One">
     <HubSection>
     </HubSection>
     <HubSection Header="Qué es" Width="500">
     </HubSection>
     <HubSection Header="Juegos" Width="1200">
     </HubSection>
</Hub>

El resultado:

Ya tenemos secciones.

Ya tenemos secciones.

Nos centramos en la primera sección. Ya hemos comentado que vamos a añadir un banner que cubra una zona importante para llamar la atención del usuario junto a un titular. Dado que queremos cubrir toda la zona de la sección con la imágen la estableceremos como fondo:

<HubSection Width="800">
     <HubSection.Background>
          <ImageBrush ImageSource="/Assets/Xbox.jpg" Stretch="UniformToFill"/>
     </HubSection.Background>
</HubSection>
Vamos mejorando

Vamos mejorando

Y el titular, simple, ¿o no?. Las secciones del control Hub soportan cualquier tipo de contenido, desde un simple botón a un complejo GridView sin embargo no tienen ninguna propiedad Content. Estableceremos el contenido estableciendo su DataTemplate:

<DataTemplate>
     <RichTextBlock>
          <Paragraph FontSize="32">
          Te damos la bienvenida a una nueva generación!
          </Paragraph>
     </RichTextBlock>
</DataTemplate>

Pasamos a la segunda sección. En esta sección vamos a añadir información sobre la consola. Vamos a utilizar para ello el control RichTextBox:

<DataTemplate>
     <RichTextBlock>
          <Paragraph FontSize="20">
          Te damos la bienvenida a una nueva generación de juegos y entretenimiento. En la que los juegos superan las barreras del realismo. Y puedes escuchar música mientras juegas. Donde puedes pasar de ver la TV a películas, música y juegos en un instante. Y vivir una experiencia totalmente personalizada. Donde todo lo que te entretiene está en un solo lugar. Esto es Xbox One, el sistema que lo incluye todo.
          </Paragraph>
          <Paragraph FontSize="20">
          Xbox One es una modernísima consola de juegos, una TV de última generación, un centro de cine en casa y muchísimo más. Los días en los que tenías que cambiar los enchufes de la TV para jugar o ver una película han pasado a la historia. Con Xbox One, puedes pasar rápidamente de la TV a películas, música o juegos. Solo necesitas tu voz para hacerlo.
          </Paragraph>
     </RichTextBlock>
</DataTemplate>

Otro de los controles añadidos en Windows 8.1 es el control Hyperlink. Nos permite definir enlaces dentro del texto enriquecido. La interpretación del texto es exactamente igual al resto con la única diferencia de ser marcado con un color diferente y por supuesto que al ser pulsado nos redirige a una URI especificada.

Añadimos al RichTextBox un enlace:

<Hyperlink FontSize="28" Foreground="DarkGreen" NavigateUri="http://www.xbox.com/es-ES/xboxone/meet-xbox-one">Sorpréndete.</Hyperlink>

La propiedad fundamental del control Hyperlink es NavigateUri donde especificamos la URI a donde se navegará al pulsar el enlace.

El resultado hasta ahora:

Segunda sección preparada

Segunda sección preparada

Vamos a por la tercera sección. En esta sección vamos a añadir un control de mayor peso añadiendo un GridView donde mostrar el listado de juegos de la consola.

Creamos una carpeta “Models” donde definiremos la clase Games donde almacenaremos la información de cada juego:

public class Game
{
     public string Title { get; set; }
     public string Description { get; set; }
     public string Image { get; set; }
}

A continuación, creamos una carpeta “ViewModels” donde prepararemos la colección de juegos que se mostrará en la vista:

public class MainViewModel
{

     public List<Game> Games
     {
          get;
          set;
     }

     public MainViewModel()
     {
          Games = new List<Game>();
          Games.Add(new Game { Title = "Forza Motorsport 5", Description = "Forza Motorsport, la franquicia de carreras mejor valorada de la última década, vuelve con una experiencia de conducción total de última generación creada en exclusiva para Xbox One.", Image = "http://compass.xboxlive.com/assets/cb/19/cb19177d-969a-48dc-91f2-d6e8416968d6.jpg?n=XBR_Game1.jpg" });
          Games.Add(new Game { Title = "Ryse", Description = "En medio del caos de la última etapa del Imperio Romano, conviértete en el soldado Marius Titus y súmate a una trepidante campaña para vengar la muerte de tu familia.", Image = "http://compass.xboxlive.com/assets/69/d2/69d2d734-7a15-40b5-a7b9-9baea1937c40.jpg?n=XBR_Game4.jpg" });
          Games.Add(new Game { Title = "Dead Rising 3", Description = "Todo vale como arma en Dead Rising 3. Explora la ciudad de Los Perdidos (California) como Nick Ramos, un mecánico con un pasado misterioso, que debe encontrar el modo de escapar antes de que un ataque militar acabe con la ciudad y todos sus habitantes.", Image = "http://compass.xboxlive.com/assets/83/c7/83c74b66-5f24-4263-bc03-3c3c021c4a11.jpg?n=XBR_Game5.jpg" });
          Games.Add(new Game { Title = "Call of Duty: Ghosts", Description = "La franquicia que ha sentado las bases de toda una generación de juegos se pone el listón aún más alto con el nuevo Call of Duty: Ghosts.", Image = "http://compass.xboxlive.com/assets/07/bb/07bbfdcf-646b-4ac9-b764-c8253e7dabc3.jpg?n=XBR_Game3.jpg" });
          Games.Add(new Game { Title = "Quatum Break", Description = "Domina el tiempo para sobrevivir al presente… y salva el futuro. De los creadores de Alan Wake y Max Payne llega Quantum Break, una experiencia de entretenimiento revolucionaria a medio camino entre el juego y la televisión.", Image = "http://compass.xboxlive.com/assets/aa/84/aa842d82-5c4e-4292-a12c-432af66f1e53.jpg?n=XBR_Game2.jpg" });
     }
}

En el code behind de la vista principal (MainPage.xaml.cs) establecemos el DataContext al ViewModel creado:

DataContext = this.DataContext ?? new MainViewModel();

Ya tenemos la infraestructura necesaria para definir nuestro listado de juegos, pasamos a la vista. Definimos un GridView:

<HubSection Header="Juegos" Width="1200">
     <DataTemplate>
          <GridView>
          </GridView>
     </DataTemplate>
</HubSection>

Hacemos Binding a la colección de juegos:

<HubSection Header="Juegos" Width="1200">
     <DataTemplate>
          <GridView SelectionMode="None"
          ItemsSource="{Binding Games}">
          </GridView>
     </DataTemplate>
</HubSection>

Establecemos el DataTemplate con la defnición de como se verá cada juego en la lista y como están organizados:

<HubSection Header="Juegos" Width="1200">
     <DataTemplate>
          <GridView SelectionMode="None" ItemTemplate="{StaticResource Standard310x260ItemTemplate}"
          ItemsSource="{Binding Games}">
               <GridView.ItemsPanel>
                    <ItemsPanelTemplate>
                        <WrapGrid Orientation="Horizontal"/>
                    </ItemsPanelTemplate>
               </GridView.ItemsPanel>
          </GridView>
     </DataTemplate>
</HubSection

Si ejecutamos obtendremos el siguiente resultado:

GridView como sección del Hub

GridView como sección del Hub

NOTA: Al GridView de la sección no se puede acceder desde el code behind aun asignándole un nombre.

IsHeaderInteractive=”True”

Lo visto hasta ahora del control es muy interesante pero sería insuficiente para poder gestionar toda la lógica necesaria en una aplicación real. En nuestro ejemplo sobre la nueva Xbox One mostramos un listado de juegos. Lo ideal sería mostrar el listado de juegos top, los más recientes o lo más destacados por ejemplo y al pulsar sobre la cabecera, mostrar una vista de detalles con el listado completo de juegos.

Efectivamente os sonará esta posibilidad a la ya utilizada en el control GridView por ejemplo.

¿Es posible realizarlo?

Claro!. Las secciones del control Hub cuentan con una propiedad para activar esta posibilidad llamada isHeaderInteractive:

<HubSection Header="Juegos" Width="1200" IsHeaderInteractive="True"/>

Ahora debemos añadir el evento clic que se produce al pulsar las cabeceras:

<Hub Header="Xbox One" SectionHeaderClick="Hub_SectionHeaderClick" />

Por último, en el controlador del evento clic podemos determinar con facilidad la cabecera pulsada gracias al EventArgs del evento:

private void Hub_SectionHeaderClick(object sender, HubSectionHeaderClickEventArgs e)
{
     if(e.Section.Name == "Juegos")
     {
          //Navegamos a la vista de detalles!
     }
}

Podéis ver el resultado del ejemplo en el siguiente video:

También podéis descargar el código fuente del ejemplo desde el siguiente enlace:

Espero que lo visto en la entrada os sea de interés. Recordar que si os surgen dudas o sugerencias podéis dejarlas en los comentarios de la entrada.

Keep Pushing!

Más información

Novedades de Windows 8.1

Introducción

Recientemente se han presentado grandes novedades para los desarrolladores .NET en el marco del //BUILD 2013. Se ha liberado Windows 8.1 Preview junto a Visual Studio 2013 Preview. Podéis descargar Windows 8.1 Preview desde http://preview.windows.com y Visual Studio 2013 Preview desde la página de descargas del Dev Center.

Windows 8.1 Preview

Windows 8.1 Preview

Windows 8.1. Novedades como sistema

La vuelta del botón inicio

Se rumoreaba desde hace tiempo con capturas filtradas y múltiples suposiciones. Algunos usuarios no se encontraban agusto sin el botón inicio. Ha vuelto. Pero esperad, no es el botón inicio tradicional que conocéis, si lo pulsamos nos guía a la interfaz Modern UI. Si hacemos clic derecho nos aparecerá un popup con acceso rápido a múltiples opciones desde acceder a la interfaz Modern UI a apagar el sistema.

Vuelve el botón inicio!

Vuelve el botón inicio!

También ha sido atendida otra petición pública bastante extendida que pedía el poder acceder directamente al escritorio clásico sin pasar por la interfaz Modern UI.

Nuevos tiles!

Contamos con dos nuevos tamaños para tiles permitiendos una mayor libertad a la hora de gestionar nuestro escritorio Modern UI.

Nuevos Tiles

Nuevos Tiles

Multitarea mejorada

Si en Windows 8 una de las características más interesantes era la multitarea y la posibilidad de tener dos aplicaciones de manera simultánea. En Windows 8.1 podemos tener hasta cuatro aplicaciones a la vez pudiendo además marcar el tamaño elegido para cada una de ellas.

NOTA: Al igual que en Windows 8 se deben de cumplir unos requisitos mínimos de resolución.

Búsquedas más potentes

En la barra de charms seguimos contando con la posibilidad de realizar de manera rápida búsquedas en el sistema y las aplicaciones. Ahora se añaden integración con archivos skydrive, el disco duro o las aplicaciones integradas en el sistema en una nueva interfaz (impresionante) que nos permite realizar acciones directas con rapidez como reproducir un video o un audio directamente.

Búsquedas

Búsquedas

Nueva tienda

Se ha rediseñado el aspecto de la tienda en una búsqueda de mayor usabilidad permitiendo encontrar o descubrir con más rapidez lo buscado. La novedad más atractiva en este punto son las actualizaciones automáticas de las aplicaciones.

Otros cambios

  • Soporte nativo para impresoras 3D.
  • LockScreen mucho más versátil.
  • Mejoras en Xbox Music.
  • Nuevas aplicaciones!
  • Más idiomas soportados (139!).
  • Etc.

En definitiva se han reforzado todas las partes importantes del sistema atendiendo también a las peticiones más importantes del público. Podéis ver un resúmen de las novedades en el siguiente video:

Lo que nos interesa, novedades en el desarrollo!

Mejoras en os Live Tiles

Los Tiles (baldosas) son uno de los pilares fundamentales de la atractiva interfaz de usuario que tenemos disponible en Windows 8.

En Windows8.1 nos ofrecerán una mayor flexibilidad y oportunidades en nuestras aplicaciones. Ahora podremos definir el live tile en el archivo de manifiesto de modo que comenzará a actualizarse de inmediato sin la necesidad de que el usuario abra e interaccione con la Aplicación.

Además, contamos con nuevos tamaños:

  • Small Tiles: 70x70px
  • Large Tiles: 310x310px
Nuevos Tiles!

Nuevos Tiles!

Recordar que en Windows 8 ya contábamos con dos tamaños de tiles:

  • Square Tiles: 150x150px
  • Wide Tiles: 310x150px

Por lo tanto ahora contamos con hasta 4 tipos diferentes de tiles. Para facilitar su identificación han sido renombrados:

  • Small = Square 70x70px
  • Medium = Square 150x150px
  • Wide = Wide 310x150px
  • Large = Square 310x310px

NOTA: Por compatibilidad los nombres antiguos siguen siendo válidos aunque se recomienda utilizar los nuevos.

Nuevos Controles!

Se han añadido mútiples controles nuevos tanto para XAML como para WinJS:

En XAML contamos con:

AppBar. En Windows 8.1 contamos un nuevos controles que nos permiten crear botones para el ApplicationBar que reflejen y respeten las guías de diseño y comportamiento establecidas sin grandes esfuerzos por parte de los desarrolladores. Contamos con tres tipos diferententes de controles:

Las diferencias con respecto a botones normales serían:

  • Por defecto son circulares en lugar de rectangulares.
  • Su contenido se establece con las propiedades Label e Icon en lugar de la propiedad Content.

El ejemplo básico de un AppBarButton sería:

<AppBarButton Icon="Test" Label="Example" Click="AppBarButton_Click"/>

Mientras que un AppBarToggleButton se definiría asi:

<AppBarToggleButton Label="Example" Click="AppBarButton_Click">
    <AppBarToggleButton.Icon>
        <PathIcon Data="F1 M 20,20L 24,10L 24,24L 5,24"/>
    </AppBarToggleButton.Icon>
</AppBarToggleButton>

Por último, un separador visual entre los botones, es decir, el AppBarSeparator se define:

<AppBarSeparator />

CommandBar. Este control nos facilita la creación de ApplicationBar en nuestras aplicaciones. El control nos proporciona:

  • Layout adecuados con botones principales alineados a la izquierda y los botones secundarios alineados a la derecha.
  • Autoescala los botones para adaptarse a cambios de resolución o de orientación.
<Page.BottomAppBar>
    <CommandBar>
        <AppBarButton Icon="Back" Label="Back" Click="AppBarButton_Click"/>
        <AppBarButton Icon="Stop" Label="Stop" Click="AppBarButton_Click"/>
        <AppBarButton Icon="Play" Label="Play" Click="AppBarButton_Click"/>
        <AppBarButton Icon="Forward" Label="Forward" Click="AppBarButton_Click"/>
        <AppBarSeparator/>
        <AppBarToggleButton Icon="Shuffle" Label="Shuffle" Click="AppBarButton_Click"/>
        <AppBarToggleButton Icon="RepeatAll" Label="Repeat" Click="AppBarButton_Click"/>
        <CommandBar.SecondaryCommands>
            <AppBarButton Icon="Like" Label="Like" Click="AppBarButton_Click"/>
            <AppBarButton Icon="Dislike" Label="Dislike" Click="AppBarButton_Click"/>
        </CommandBar.SecondaryCommands>
    </CommandBar>
</Page.BottomAppBar>

DatePicker.  Lo habíais echado de menos, ¿verdad?. Nuevo control destinado a capturar fechas en tus aplicaciones.

DatePicker

DatePicker

Diseñado para funcionar con teclado y ratón además de por supuesto táctil. Su uso muy simple:

<DatePicker x:Name=myDatePicker Header="Introduzca la fecha:"/>

Podemos establecer la fecha (propiedad Date) desde código o haciendo Binding a una instancia de tipo DateTimeOffset.

Por supuesto el control es altamente personalizable utilizando estilos y plantillas y soporta los layouts horizontales y verticales.

Flyout. Control destinado a mostrar en un popup temporal contenido adicional relacionado con la acción realizada por el usuario.

Flyout

Flyout

Hub. Destinado a reproducir con facilidad el patrón de diseño Hub ya visible en múltiples aplicaciones. El control Hub como ya hemos mencionado nos permite definir la estructura base de nuestra aplicación (tal y como nos lo permitía el control GridView por ejemplo). Nos permite estructuar la información en secciones donde lo más importante y atractivo visualmente se colocará a la izquierda mientras que el resto de opciones donde se profundiza más en la información se situa más a la derecha. El usuario accede a la información extra haciendo scroll horizontal. El objetivo del control es permitir mostrar la información con el mayor atractivo visual posible para atraer al usuario a descubrirla.

<Hub Header="News">
    <HubSection MinWidth="600" Header="Latest">
        <DataTemplate>
            <Grid>
            </Grid>
        </DataTemplate>
    </HubSection>

    <HubSection Header="Tech" IsHeaderInteractive="True" MinWidth="250">
        <DataTemplate>
            <StackPanel>

            </StackPanel>
        </DataTemplate>
    </HubSection>

    <HubSection Header="Sports" IsHeaderInteractive="True" MinWidth="250">
        <DataTemplate>
            <StackPanel>

            </StackPanel>
        </DataTemplate>
    </HubSection>
</Hub>
Hub

Hub

Hyperlink. Control que nos permite añadir enlaces. El tratamiento que recibe es exactamente igual al resto del texto. La diferencia se aplica asignándole un color diferente y que al ser pulsado navega a una URI. Su uso sencillo:

<RichTextBlock Width="200" Style="{StaticResource BasicRichTextStyle}">
    <Paragraph>Hyperlinks let you give readers a visual hint that certain text links to other content.
        <Hyperlink NavigateUri="http://dev.windows.com">Read more on the Windows Dev Center</Hyperlink>
        ... Text in a Hyperlink element is treated like the rest of the text and participates in line breaking.
    </Paragraph>
</RichTextBlock>
Hyperlink

Hyperlink

MenuFlyout. Control que nos pemite mostrar un popup temporal con un listado de opciones. Lo utilizaremos para que el usuario pueda elegir una opción entre varias opciones. Se oculta cuando el usuario pulsa sobre una opción o al pulsar fuera del control.

<Button Content="Options">
    <Button.Flyout>
        <MenuFlyout>
            <MenuFlyoutItem Text="Reset"/>
            <MenuFlyoutSeparator/>
            <ToggleMenuFlyoutItem Text="Shuffle" IsChecked="{Binding IsShuffleEnabled, Mode=TwoWay}"/>
            <ToggleMenuFlyoutItem Text="Repeat" IsChecked="{Binding IsRepeatEnabled, Mode=TwoWay}"/>
        </MenuFlyout>
    </Button.Flyout>
</Button>
MenuFlyout

MenuFlyout

SettingsFlyout. Control que nos permite crear flyouts de configuración de manera fácil respetando todos los puntos de las guías de estilo.

SettingsFlyout

SettingsFlyout

TimePicker. Control que nos permite capturar tiempos en nuestras aplicaciones. Diseñado para funcionar con teclado y ratón además de por supuesto táctil. Su uso muy simple:

<TimePicker x:Name=myTimePicker Header="Insert Time"/>
TimePicker

TimePicker

En WinJS también tenemos un listado de nuevos controles:

Otras novedades

Entre una lista considerable de cambios en la API podemos destacar:

  • Cambios en la gestión de temas. En Windows 8 el tema de la aplicación se establecía una vez en arranque y no se podia cambiar dinámicamente o establecerlo a zonas concretas (controles determinados por ejemplo). En Windows 8.1 podemos hacer ambas cosas.
  • Nueva API Scheduler. Nos permite definir la prioridad de los tasks pudiendo desarrollar aplicaciones más adaptadas eficientemente a los recursos del sistema.
  • Nueva API Http Client (HTTP y REST).
  • Mejoras múltiples de rendimiento (mejorado hasta en un 40% Bindings).
  • Mejoras en el sistema de bindings (TargetNullValue, Fallback Value, etc).

En definitiva,  más de 650 nuevas APIs disponibles en Windows 8.1!. ¿No os entran ganas de “hincarle” el diente?. En próximas entradas iremos analizando las posibilidades que nos brindan los nuevos controles asi como las nuevas APIs disponibles.

Keep Pushing!

Más información