[Windows 8] Value Converters

Posted on


Artículo escrito por: Néstor Fernández.

Twitter: @xamlparaadeptos

COLECCIONES QUE REPORTAN CAMBIOS

Los bindings son muy útiles cuando necesitamos mantener algo de sincronía entre los valores de dos propiedades. Sin embargo, no es fácil implementar un binding en algunas ocasiones:

  • Cuando las dos propiedades son de tipos diferentes.
  • Cuando el origen es un objeto y no una propiedad.
  • Cuando, aunque del mismo tipo, el valor en el origen no es exactamente el que queremos llevar hasta el destino.

Para cualquiera de estas necesidades contamos con los converters. Un converter es una clase que se conecta a un binding y puede alterar el valor que pasa desde la propiedad de origen al destino y/o viceversa. Estas clases implementan la interfaz IValueConverter que solo requiere definir dos métodos:

  • Convert: Que se invoca cuando el valor de la propiedad de origen viaja hasta la propiedad de destino.
  • ConvertBack: Que se invoca cuando el valor de la propiedad de destino viaja hasta la propiedad de origen.
DEFINICIÓN DE UN CONVERTER

En su representación más simple un converter se define así:

   1:  public class MiConverter : IValueConverter
   2:  { 
   3:     public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { }
   4:     public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { }
   5:  }

Los converters, al no ser controles, deben incluirse preferiblemente en un diccionario de recursos:

   1:  <Page.Resources>
   2:      <local:MiConverter x:Key="LlaveConverter" />
   3:  </Page.Resources> 

Y en un binding se asignan a la propiedad Converter de dicho binding:

   1:  <TextBox Text="{Binding Path=Fecha, Converter={StaticResource LlaveConverter}}" />

EJEMPLOS

Para los ejemplos utilizaremos el siguiente escenario: Una clase como nuestra fuente de datos:

   1:  public class ClasePersona
   2:  {
   3:      public string Nombre { get; set; }
   4:          public DateTime FechaNacimiento { get; set; }
   5:      public int Saldo { get; set; }
   6:  }

A su vez la instanciaremos directamente en XAML y la definiremos como el DataContext de un Grid dentro de una página. El converter que utilizaremos también lo definiremos dentro del diccionario de recursos de una página:

   1:  <Page.Resources>
   2:      <local:ClasePersona x:Key="Persona" Nombre="Aura Fernandez" FechaNacimiento="9/13/1969" Saldo="12500" />
   3:      <local:MiConverter x:Key="LlaveConverter" />
   4:  </Page.Resources>
   5:   
   6:  <Grid DataContext="{StaticResource Persona}">
   7:      ...
   8:  </Grid>

EJEMPLO 1

Este converter puede tomar un dato del tipo DateTime y convertirlo en el nombre del mes correspondiente a esa fecha. Nótese que para este ejemplo el binding no está definido como TwoWay, de modo que no es necesario definir el método ConvertBack.

   1:  public class MiConverter : IValueConverter  public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
   2:      {
   3:          int NumeroMes = ((DateTime)value).Month;
   4:          return System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat.MonthNames[NumeroMes];
   5:      }
   6:   
   7:      public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
   8:      { return null; }
   9:  }

Y así se utilizan dentro de, por ejemplo, un TextBlock:

   1:  <Grid DataContext="{StaticResource Persona}">
   2:      <TextBlock Text="{Binding Path=FechaNacimiento, Converter={StaticResource LlaveConverter}}" />
   3:  </Grid> 

En este caso debemos observar en el TextBlock la cadena "septiembre".

EJEMPLO 2

Aquí tenemos un converter que toma una cadena y devuelve una brocha. Lo utilizaremos para crear una ayuda visual que se torne roja cuando la cadena esté vacía o contenga menos de 5 caracteres, o de lo contrario que cambie a verde. De esta forma podemos, por ejemplo, informar visualmente al usuario cuando una regla o condición no se esté cumpliendo.

   1:   public class MiConverter : IValueConverter
   2:  {
   3:      static SolidColorBrush ColorRojo = new SolidColorBrush(Colors.Red);
   4:      static SolidColorBrush ColorVerde = new SolidColorBrush(Colors.Green);
   5:   
   6:      public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
   7:      {
   8:        var Texto = System.Convert.ToString(value);
   9:        if (string.IsNullOrWhiteSpace(Texto) || Texto.Length < 5)
  10:          return ColorRojo;
  11:        else
  12:          return ColorVerde;
  13:      }
  14:   
  15:      public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
  16:      {
  17:        return null;
  18:      }
  19:  }

Lo podemos utilizar, por ejemplo, como color de fondo de cualquier otro elemento:

   1:  <Ellipse Width="100"
   2:           Height="100"
   3:           Fill="{Binding Path=Nombre, Converter={StaticResource MiConverter}}" />

EJEMPLO 3

Este converter nos facilitará calcular un impuesto cualquiera para un un valor numérico. Obsérvese el uso del parámetro "parameter" que podemos asignar convenientemente desde el binding. En otras palabras este binding recibe dos valores: el valor enlazado por el binding y uno adicional (parameter) que utilizaremos para indicar el porcentaje del impuesto.

   1:  public class ImpuestoConverter : IValueConverter
   2:  {
   3:    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
   4:    {
   5:      int Valor = System.Convert.ToInt32(value);
   6:      double Impuesto = System.Convert.ToDouble(parameter);
   7:      return (Valor * Impuesto / 100).ToString("#,##0.00");
   8:    }
   9:   
  10:    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
  11:    {
  12:      return null;
  13:    }
  14:  }

Y lo utilizamos así:

   1:  <TextBlock Text="{Binding Path=Saldo, Converter={StaticResource ImpuestoConverter}, C}, ConverterParameter=16.5}" />

PARA SABER MÁS… Converting data for display in controls

Un comentario sobre “[Windows 8] Value Converters

    Resumen Post 2012 « Todo en ASP.NET escribió:
    12/19/2012 en 22:06

    […] [Windows 8] Value Converters […]

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s