Data Binding en WPF. 3º Parte. Converters.

En muchas ocasiones lo que tomamos de la base de datos no esta con el formato adecuado para mostrar en la interfaz de usuario. Por ejemplo, obtenemos un decimal de la base de datos con un precio pero deseamos mostrar dicho valor adecuadamente ( 10 € por ejemplo ).

Por suerte, WPF incorpora funcionalidad bastante potente destinada a realizar conversiones de datos de cara a prepararla para la interfaz de usuario.

IValueConverter

El eje central de las conversiones las lograremos implementando la interfaz IValueConverter.
Esta interfaz nos exigira implementar dos métodos:

Convert. Convierte un tipo de entrada en otro de salida.
ConvertBack. Nos realiza la operación inversa.

Veamos a continuación, como sería una implementación vacía de la interfaz:

public class miConversor : IValueConverter
{
     public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
     {

     }

     public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
     {

     }
}

El método convert convierte el valor del objeto value y se devuelve como un objeto de salida en el mismo método (fíjate que el método converter devuelve un tipo object).

El metodo convertback realiza la operación inversa siempre y cuando se pueda realizar. Comentamos siempre  cuando, porque en ocasiones no se podrá realizar la operación inversa. En dichos casos, y sabiendo que nunca lo llamaremos lo mejor es no implementar de manera explícita el método convertback. Evitar hacer esto a toda costa si el binding que utiliza el converter es en modo two-way.

Para definir el converter de manera adecuada también se deberá añadir a la clase el atributo ValueConversion.
Este atributo definira el tipo del objeto de entrada a convertir, y el tipo del resultado una vez convertido.
Para entender esto mejor, veamos un ejemplo muy sencillo. Vamos a convertir un entero a string:

[ValueConversion(typeof(int), typeof(string))]

Ya hemos hablado mucho de converters sin ver ningún ejemplo completo. Imaginate que en una base de datos tienes un entero que simboliza en nivel de calidad de una película:

1      Horrible
2      Mala
3      Regular
4      Buena
5      Obra Maestra

Tras obtener un valor de la base de datos (por ejemplo, el valor 3), lo ideal no es hacer el binding sin mas a la interfaz porque de cara al usuario final, un 3 no le puede decir nada.

¿que hacemos?

Un converter. Veamos como sería:


namespace EjemploConverter;

[ValueConversion(typeof(int), typeof(string))]
public class intToStringConverter : IValueConverter
{
 public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
 {
      int a = int.Parse(value,toString());

      switch(a)
      {
            case 1:               return "Horrible";
            case 2:               return "Mala";
            case 3:               return "Regular";
            case 4:               return "Buena";
            case 5:               return "Obra Maestra";
            default:              return "Sin clasificación";
      }
 }

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
 {
      string a = value.toString();

      switch(a)
      {
            case "Horrible":               return 1;
            case "Mala":                   return 2;
            case "Regular":                return 3;
            case "Buena":                  return 4;
            default:                       return 5;
      }
 }
}

¿Bien hasta aquí?. La siguiente pregunta lógica es, ¿cómo uso el converter en el XAML?

Lo primero que debemos hacer es añadir una referencia al namespace donde está definido el converter.

<Windowx:Class="EjemploConverter.Window1"
...   xmlns:converter="clr-namespace:EjemploConverter"    ...>
 ...
</Window>

A continuación, lo que debemos hacer es crear una instancia del converter, normalmente se realiza en la colección de recursos:

<Window.Resources>
     <converter:intToStringConverterx:Key="converter"/>
</Window.Resources>

Después de crear la instancia del mismo, debemos utilizarlo en el binding establenciendolo en la propiedad Converter.

<Grid>
     <Label Content="{Binding filmCode,  Converter={StaticResource converter}}"/>
</Grid>

Usar Converters para lograr distintos formatos

Uno de los grandes usos de los converters es el de dar distintos formatos a string de cara a la interfaz de usuario.
Ya hemos visto anteriormente un ejemplo de esto. Casos como:

– Fechas
– Monedas
– Documentos varios (número de la seguridad social, número N.I.F, etc.)

Dando formato a monedas

Es el ejemplo más sencillo que podemos analizar de como utilizar converters para dar formato a string. Normalmente, en la base de datos almacenados los valores monetarios sin formato. Cuando obtenemos el valor de la base de datos (por ejemplo, un decimal de valor 7,95) queremos que en la capa visual se muestre el valor con formato, es decir, en el caso del ejemplo anterior, 7,95 €.
Para conseguir el resultado deseado podemos utilizar el método ToString de los valores numéricos. Sólo debemos insertar el carácter ‘C’ como mostramos a continuación:

string resultadoMoneda = miDouble.ToString("C");

Con esta sencilla operación podemos obtener un valor numérico por ejemplo un Decimal dentro del método Convert de un converter y transformarlo en un string formateado. Es decir, crearíamos un converter que recibe un decimal y devuelve un string.
Veamos como sería:

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
     decimal valor = decimal.Pare(value.ToString());

     return a.ToString("C");
}

Nada más por hoy. Espero que la entrada os resulte útil. Hasta la próxima.

Un pensamiento en “Data Binding en WPF. 3º Parte. Converters.

  1. Hola.
    Un artículo bien explicado y sencillo de entender.
    Una pregunta ¿como puedo utilizar una Clase Convert en un DataGrid que esta enlazado a un DataTable o mejor dico a un List?
    Gracias.

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