lunes, 27 de diciembre de 2010

[Silverlight] Convirtiendo tipos para DataTemplates

Una de las armas más poderosas de WPF y Silverlight son los DataTemplates, que te permiten especificar un template y después mediante el DataBinding puedes desplegar todos los datos de forma automática sin necesidad de rellenarlos a “pelo” insertando fila por fila.

Pero en algunas ocasiones se necesitará contemplar elementos que deben aparecer o no en función de algunos valores de lógica. Por ejemplo, en mi lógica dispongo de una clase Item que tiene una propiedad booleana llamada Borrowed. Cuando esta propiedad está a true, debe aparecer un botón, y cuando no lo está, no debe aparecer nada. En Silverlight la propiedad Visibility permite especificar la visibilidad de un elemento cualquiera, pero esta propiedad se ajusta a través de un enumerado que indica si es visible ( Visible ) o no (Collapsed). Como medida sucia podría incluir dentro de mi lógica una propiedad que tuviera ese valor, pero entonces estaría causando una dependencia entre la lógica y la interfaz de la aplicación y como todos sabemos, eso nunca es bueno. Para solventar este tipo de cosas usaremos un Converter junto con el Binding. Vayamos por partes.

Usaremos el converter para transformar el valor de una propiedad en otro. En nuestro caso, transformaremos el valor booleano de Borrowed por el valor Visible de la interfaz. Para ello crearemos una clase que implemente la interfaz IValueConverter. Esta interfaz consta de dos métodos, Convert y ConvertBack. En nuestro caso vamos a implementar únicamente el Convert, ya que el ConverBack se usará en sentido inverso (de interfaz a lógica).

   1: public class BorrowedToVisibilityConverter : System.Windows.Data.IValueConverter
   2:     {
   3:         #region IValueConverter Members
   4:  
   5:         public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
   6:         {
   7:             Visibility isVisible = Visibility.Collapsed;
   8:             if ((value == null))
   9:                 return isVisible;
  10:             if (((bool)value))
  11:             {
  12:                 isVisible = Visibility.Visible;
  13:             }
  14:             return isVisible;
  15:         }
  16:  
  17:         public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
  18:         {
  19:             throw new NotImplementedException();
  20:         }
  21:  
  22:         #endregion


Dentro de Convert interesa el parámetro value (lo que vamos a usar para convertir). El resto de parámetros no interesa en este caso, pero no es necesario explicarlos. Como se puede apreciar el código es sencillo, si el valor es positivo se devuelve Visibility.Visible y en cualquier otro caso se devuelve Visibiliy.Collapsed. Ahora teniendo esto ya implementado, tenemos que asociarlo a nuestro binding y por ello, a partir de este momento nos dedicamos ya con el fichero XAML correspondiente.

Ante de asociarlo, tenemos que mapear este conversor como un recurso. Para ello simplemente le asignamos una clave de referencia y especificamos el nombre del conversor:

   1: <UserControl.Resources>
   2:          <converter:BorrowedToVisibilityConverter x:Key="BorrowedToVisibility" />
   3: </UserControl.Resources>

Y por último lo asociamos a nuestro binding. En este caso irá en un botón en el su propiedad Visibility dependerá del valor de la propiedad Borrowed del binding asociado al template. Es aquí cuando ya debemos especificar el conversor de forma explícita:

   1: <Button Content="Ok!" Height="72" Width="160"  Visibility="{Binding Borrowed, Converter={StaticResource BorrowedToVisibility} }" HorizontalAlignment="Right" Click="Button_Click" Tag="{Binding Id}" Background="White" BorderBrush="Black" Foreground="Black" />

Y más en detalle:

   1: Visibility="{Binding Borrowed, Converter={StaticResource BorrowedToVisibility} }" 

Asociamos la propiedad del objeto y le indicamos que tenemos un conversor, incluido como recurso estático y su clave de referencia.

No hay comentarios:

Publicar un comentario