Hace unos días os contaba qué es el patrón MVVM y cómo se utiliza. Así que hoy vamos a ha ver un ejemplo sencillo de como podemos utilizar el enlace de datos o binding en nuestra aplicación Windows Phone para aprovecharnos de las ventajas de usar este patrón. El ejemplo es bastante sencillo, pero será suficiente para ilustrar como enlazar propiedades y colecciones con nuestra vista XAML.
Nota: el ejemplo lo podéis descargar desde aquí. El proyecto está desarrollado para Windows Phone 8, así que necesitaréis Windos Phone SDK que podéis descargar desde aquí.
Creando el modelo
Está claro que cuándo creamos una aplicación para Windows Phone lo más normal es necesitar una lógica de negocio compleja. Para recuperar nuestros datos necesitaremos consultar un servicio web, una API u otros servicios externos. Pero como todas esas operaciones están alejadas del objetivo de esta entrada, nuestro modelo de datos va a ser muy sencillo.
Nuestra aplicación mostrará datos de una línea de teléfono (número y operador), así como una lista con las últimas llamadas de esa línea. El modelo es el siguiente:
{
public string Contacto { get; set; }
public string NumeroTlf { get; set; }
public string Tipo { get; set; }
public DateTime Fecha{get;set;}
}
public class ListaLlamadas : ObservableCollection<Llamada>
{
public void AddLlamada(Llamada llamada)
{
this.Add(llamada);
}
}
public class AppModel
{
public string NumeroLinea { get; set; }
public string Operador { get; set; }
public ListaLlamadas llamadas;
}
La clase Llamada simplemente contiene las propiedades típicas que se pueden asociar a una lllamada, como número de teléfono, nombre del contacto, el tipo (entrante o saliente) y la fecha. Todas esas llamadas van asociadas a una línea de teléfono, que representa la clase AppModel y que tiene propiedades como el número de línea o el operador. Además esta clase contiene una lista de llamadas, que vamos a ver más en detalle.
Para crear la lista de llamadas, hemos creado la clase ListaLlamadas que hereda de la clase ObservableCollection ¿Por qué hemos hecho esto y no hemos usado una clase List? Pues porque esta clase implementa la interface INotifyCollectionChanged, lo que hace que se lance un evento CollectionChanged cada vez que se hacen cambios en la colección.
Aunque todavía no lo vamos a usar en este ejemplo, este evento nos ayudará a realizar un binding de la colección, de manera que la vista cambie cuándo se añaden o eliminan elementos de la lista de llamadas. Así que por ahora, nos quedamos con que es una lista a la que se le añaden las llamadas.
En el modelo también hemos implementado una clase estática, que contiene el método getLineaModel, que lo único que hace es generar un objeto AppModel, incluyendo una lista de llamadas de ejemplo.
Creando la vista-modelo
Nuestra vista-modelo se llamará MainViewModel, de la misma manera que nuestra página XAML.
{
private string _NumeroLinea;
public string NumeroLinea
{
get
{
return _NumeroLinea;
}
set
{
if (value != _NumeroLinea)
{
_NumeroLinea = value;
NotifyPropertyChanged(“NumeroLinea”);
}
}
}
private string _Operador;
public string Operador
{
get
{
return _Operador;
}
set
{
if (value != _Operador)
{
_Operador = value;
NotifyPropertyChanged(“Operador”);
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (null != handler)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
Esta clase es bastante sencilla y tan solo presenta dos propiedades llamadas NumeroLinea y Operador, ambas del tipo string. Estas propiedades tienen sus correspondientes set y get para establecer los valores. Y es en el set de cada propiedad, dónde encontramos el meollo del asunto. Cada vez que se cambia el valor de una de las propiedades se ejecuta el método NotifyPropertyChanged que lanzará un evento PropertyChanged con el nombre de la propiedad que ha sido cambiada. Este evento lo tenemos que lanzar porque nuestra clase implementa la interface INotifyPropertyChanged.
De esta manera, cuando una propiedad cambia, se lanza un evento de este tipo, y si tenemos enlazada la propiedad en la vista, la vista cambiará automáticamente.
Creando la vista
La vista tiene bastante código, así que no la voy a poner entera, si no por partes.
Lo primero que vamos a ver, es como hemos enlazado las dos propiedades que están en nuestra vista-modelo con nuestra vista. En este caso, las hemos enlazado a dos elementos TextBox.
<TextBlock>Línea de teléfono</TextBlock>
<TextBox Text=“{Binding NumeroLinea}”></TextBox>
<TextBlock>Operador</TextBlock>
<TextBox Text=“{Binding Operador}”></TextBox>
</StackPanel>
Si os fijaís en el atributo Text de cada TextBox, hemos añadido un “{Binding NombrePropiedad}”. Ahí estamos especifícando que ese campo está enlazado con la propiedad NumeroLinea de nuestro objeto View-Model. Cuándo se lance un evento PropertyChanged, la vista lo capturará, y modificará el texto del TextBox correspondiente.
Ya podéis ver, que hacer un binding de propiedades es un juego de niños. Ahora vamos a crear un enlace a una lista, que aunque no es difícil, tiene un poquito más de historia. La parte del XAML que nos importa es la siguiente.
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation=“Vertical” Margin=“0,0,0,10”>
<TextBlock Name=“contacto" Text=”{Binding Contacto}“ Foreground=”{StaticResource PhoneAccentBrush}“></TextBlock>
<StackPanel Orientation="Horizontal” FlowDirection=“LeftToRight”>
<TextBlock Text=“Teléfono:” Margin=“0,0,5,0” FontSize=“15" Foreground=”{StaticResource PhoneDisabledBrush}“></TextBlock>
<TextBlock Name="numeroTlf” Text=“{Binding NumeroTlf}” Margin=“0,0,10,0” FontSize=“15”></TextBlock>
<TextBlock Text=“Tipo:” Margin=“0,0,5,0” FontSize=“15” Foreground=“{StaticResource PhoneDisabledBrush}”></TextBlock>
<TextBlock Name=“destino” Text=“{Binding Tipo}” Margin=“0,0,10,0” FontSize=“15”></TextBlock>
</StackPanel>
<TextBlock Name=“fecha” Text=“{Binding Fecha, StringFormat=‘dd-mm-yy, hh:MM:ss’}” FontSize=“15”></TextBlock>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
En este caso, hemos creado un elemento ListBox, cuyo nombre ListaLlamadas es importante recordar, ya que lo usaremos más tarde. Para hacer un binding de una lista, dentro hemos definido una plantilla para cada elemento de la lista a través de ListBox.ItemTemplate. Dentro de esta etiqueta, especificamos la plantilla que tendrá cada elemento de la lista, la cuál crearemos de forma normal. Vamos, añadiendo Grids, TextBlocks, StackPanel o cualquier elemento que necesitemos en nuestra app Windows Phone.
Para especificar los enlaces de datos, lo hacemos de la misma manera que hemos hecho antes con las propiedades. En cada atributo Text de los TextBlock que queremos enlazar, añadimos un “{Binding NombrePropiedad}”, lo único que esta vez, los nombres de las propiedades van a ser los mismos que en la clase Llamada de nuestro modelo de datos.
¿Y con esto ya está?. Pues casi. Ahora lo que tenemos que hacer, es decirle a nuestra vista qué vista-modelo o qué lista de datos, debe utilizar.
Cargando los datos
Para decirle a la vista que datos debe utilizar, es decir que objeto vista-modelo, podemos hacerlo directamente con la propiedad DataContext de la vista. Para decirle a la lista que lista de datos contiene los elementos que tiene que representar, podemos utilizar la propiedad ItemSource. Esto lo podemos hacer desde el codebehind de nuestra vista, que en este caso se tiene un nombre tan original como MainPage. Veamos el código:
ViewModels.MainViewModel CurrentViewModel = new ViewModels.MainViewModel();
CurrentViewModel.NumeroLinea = CurrentModel.NumeroLinea;
CurrentViewModel.Operador = CurrentModel.Operador;
this.DataContext = CurrentViewModel;
this.ListaLLamadas.ItemsSource = CurrentModel.llamadas;
Como veis la operación es bastante sencilla. Primero creamos un objeto AppModel, que contiene los datos obtenidos de nuestro modelo. Recordad que nuestro modelo es muy sencillo, pero aquí es dónde debería incluirse la lógica de negocio de nuestra aplicación. Esto es, llamadas a Web Services, a APIS o cualquier otra cosa.
También instanciamos un objeto MainViewModel, al cual le asignamos las propiedades NumeroLinea y Operador que hemos obtenido de nuestro modelo. Y para finalizar, utilizamos el objeto DataContext para decirle a la vista que objeto debe utilizar.
Con la lista de llamadas hacemos algo similar, solo que en este caso utilizamos la propiedad ItemsSource del objeto ListaLlamadas Recordad que ListaLlamadas es el nombre que le dimos a la lista en el código XAML.
Y ya está. Si lanzamos la aplicación, veremos algo parecido a esto en nuestro emulador:
Conclusiones
Realizar un binding o enlace de datos en Windows Phone es muy sencillo. Pero es que además de sencillo es muy útil, y mejora la calidad del código de forma exponencial. En el próximo artículo, veremos como enlazar comandos para actualizar nuestros datos.
¿Te ha gustado el artículo? No te olvides de hacer +1 en Google+, Me gusta en Facebook o de publicarlo en Twitter. ¡ Gracias !
¿Quiéres que te avisemos cuándo se publiquen nuevas entradas en el blog? Suscríbete por RSS.
¿Quiéres que te avisemos cuando se publiquen nuevas entradas en el blog?
Suscríbete por correo electrónico o por RSS