Windows Phone –Tutorial VI ApplicationBar y MVVM

En los anteriores artículos de este tutorial hemos visto como iba poniendo botones para la navegación, pero lo lógico en toda aplicación que desarrollemos es que tengamos una barra de botones al estilo que tiene el iphone, solo que en este caso diseñados con la interfaz Metro.

Si abrimos el Xaml de la MainPage que se nos genera al crear un proyecto, podemos observar que hay una parte comentada que se refiere a la ApplicationBar

1 <!-- Sample code showing usage of ApplicationBar 2 <phone:PhoneApplicationPage.ApplicationBar> 3 <shell:ApplicationBar IsVisible="True" IsMenuEnabled="True"> 4 <shell:ApplicationBarIconButton x:Name="appbar_button1" IconUri="/Images/appbar_button1.png" Text="Button 1"></shell:ApplicationBarIconButton> 5 <shell:ApplicationBarIconButton x:Name="appbar_button2" IconUri="/Images/appbar_button2.png" Text="Button 2"></shell:ApplicationBarIconButton> 6 <shell:ApplicationBar.MenuItems> 7 <shell:ApplicationBarMenuItem x:Name="menuItem1" Text="MenuItem 1"></shell:ApplicationBarMenuItem> 8 <shell:ApplicationBarMenuItem x:Name="menuItem2" Text="MenuItem 2"></shell:ApplicationBarMenuItem> 9 </shell:ApplicationBar.MenuItems> 10 </shell:ApplicationBar> 11 </phone:PhoneApplicationPage.ApplicationBar> 12 --> 13

 

Si lo descomentamos y ejecutamos nuestra pagina seria

imageimage

 

Los botones aparecen con X porque la imagen asociada no la encuentra, y los puntos corresponde a que existe un menú como podemos observar en la segunda imagen. Los botones no pueden contener cualquier imagen (por poder si), deben de seguir las características de la interfaz metro, os recomiendo leer este articulo de la MSDN Application Bar Best Practices for Windows Phone.

Cuando instalamos las herramientas para el desarrollo de Windows Phone se nos instalan una serie de iconos en el directorio C:Program Files (x86)Microsoft SDKsWindows Phonev7.0Icons, no son muchos pero nos dan una idea.

image

De todas formas podemos crear los nuestros pero deberemos tener en cuenta además de la interfaz su tamaño

image

si no sois ningunos artistas como yo podéis comprar esta serie de 350 iconos por 10$ http://www.billybarker.net/350-mobile-app-icons-for-developers/

image

Una vez que tenemos claro que iconos vamos a utilizar tenemos que tener claro que cuando añadamos las imágenes a nuestro proyecto debemos de poner las propiedades de esa imagen

  • Copy to Output Directory: Always
  • Build Action: Content 

Esta ultima propiedad es importante las imágenes no debemos de ponerla nunca como recurso por temas de rendimiento

image

Cuando referenciamos la imagen como recurso

<Image Source="/WindowsPhoneApplication1;component/Untitled.png" />

Si nos fijamos en el fichero XAP que se genera  y lo abrimos (solo hay que cambiarlo a extensión zip) la imagen no existe en la lista de ficheros, en cambio si lo ponemos como Content, a la hora de referenciarlo es

<Image Source="Untitled.png" />

En este caso aparecerá la imagen dentro del archivo XAP como otro archivo cualquiera pero entre los ficheros XAP observaremos que este ultimo es mucho mas pequeño con lo que la descarga de tu aplicación será mas eficiente, pero también y mas importante que a la hora de inicializarse se cargar mucho mas rápido, así que tendremos que tener cuidado cuando añadamos imágenes porque por defecto y no se porque viene como Resource en vez de Content.

En mi aplicación que voy a coger la de mi anterior articulo solo tendré un botón para navegar a la siguiente pagina

1 <phone:PhoneApplicationPage.ApplicationBar> 2 <shell:ApplicationBar IsVisible="True" IsMenuEnabled="False"> 3 <shell:ApplicationBarIconButton x:Name="appbar_btnNext" IconUri="/Assets/appbar.next.rest.png" Text="Siguiente"> 4 </shell:ApplicationBarIconButton> 5 </shell:ApplicationBar> 6 </phone:PhoneApplicationPage.ApplicationBar> 7

 

Ahora deberíamos de invocarlo con un comando o con trigger asociándole EventToCommand como hemos visto anteriormente, pero en este caso es imposible ya que la clase ApplicationBarIconButton no permite ninguna de estas dos opciones con lo que debemos utilizar el code-behind. Tampoco es un sacrilegio y en este caso es absolutamente necesario

1 <phone:PhoneApplicationPage.ApplicationBar> 2 <shell:ApplicationBar IsVisible="True" IsMenuEnabled="False"> 3 <shell:ApplicationBarIconButton x:Name="appbar_btnNext" Click="appbar_btnNext_Click" IconUri="/Assets/appbar.next.rest.png" Text="Siguiente"> 4 </shell:ApplicationBarIconButton> 5 </shell:ApplicationBar> 6 </phone:PhoneApplicationPage.ApplicationBar> 7

En nuestro code-behind llamaremos al comando que queremos ejecutar

1 private void appbar_btnNext_Click(object sender, System.EventArgs e) 2 { 3 var vm = DataContext as MainViewModel; 4 5 if (vm != null) 6 { 7 vm.NavigatePage2Command.Execute(null); 8 } 9 } 10

Si lo ejecutamos la pantalla nos queda

image

Pero tenemos un problema que no funciona correctamente porque el binding del TextBox no se refresca al pulsar el botón del ApplicationBar así que lo que escribe el usuario no lo recibe la segunda página, como pasaba antes con el botón que al pulsarlo el TextBox perdía el foco y la propiedad UserText tomaba el valor. Esto ocurre también en una aplicación Silverlight la manera de solucionarlo es bien sencilla, refrescando el binding.

1 private void appbar_btnNext_Click(object sender, System.EventArgs e) 2 { 3 BindingExpression expression = txtText.GetBindingExpression(TextBox.TextProperty); 4 expression.UpdateSource(); 5 var vm = DataContext as MainViewModel; 6 7 if (vm != null) 8 { 9 10 vm.NavigatePage2Command.Execute(null); 11 } 12 } 13

 

De esta manera él binding se refresca y nuestra aplicación funciona correctamente

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *