TOC

This article has been localized into Spanish by the community.

Ligado de datos:

Conversión de valores con IValueConverter

Hasta aquí hemos utilizado asignaciones de valores simples, donde la propiedad enviada y recibida fueron siempre compatibles. Sin embargo, pronto estarás en situaciones donde querrás utilizar un valor de un tipo y luego presentarlo en forma ligeramente diferente.

Cuando utilizar un conversor de valores

Los conversores de valores son usados muy frecuentemente con asociación de datos. Aquí hay algunos ejemplos básicos:

  • Tienes un valor numérico pero quieres mostrar el cero de una manera y los números positivos de otra
  • Quieres marcar un CheckBox basado en un valor, pero el valor es un string como "si" o "no" en lugar de un valor Boolean
  • Tienes el tamaño de un archivo en bytes pero te gustaría mostrarlo como bytes, megabytes o gigabytes basado en que tan grande es

Estos son algunos de los casos más simples, pero hay muchísimos más. Por ejemplo, podrías necesitar marcar un CheckBox dependiendo de un valor booleano, pero lo quieres invertido, de manera que el CheckBox se marque si el valor es falso y se desmarque si el valor es verdadero. Incluso puedes utilizar un conversor de valores para generar una imagen desde un ImageSource, basado en el valor, como un signo verde para un valor verdadero o un signo rojo para un valor falso. Las posibilidades son infinitas.

Para casos como estos puedes usar un conversor de valores. Estas pequeñas clases, que implementan la interface IValueConverter, actuarán como intermediarios y traducirán un valor entre la fuente y el destino. Entonces, en cualquier situación donde necesites transformar un valor antes de que alcance su destino o volver nuevamente a su fuente, es probable que necesites un conversor.

Implementando un conversor de valores simple

Como fue mencionado, un conversor de valores de WPF necesita implementar la interface IValueConverter, o alternativamente, la interface IMultiValueConverter (de la que hablaremos más adelante). Ambas interfaces solo requieren que implementes dos métodos: Convert() y ConvertBack(). Como el nombre implica, estos métodos serán utilizados para convertir el valor al formato de destino y viceversa.

Implementemos un conversor simple que toma un string como entrada y devuelve un booleano, y del su versión inversa. Si eres nuevo en WPF, y probablemente lo seas teniendo en cuenta que estás leyendo este tutorial, entonces puedes no conocer todos los conceptos utilizados en el ejemplo, pero no te preocupes, serán explicados desdpués del código:

<Window x:Class="WpfTutorialSamples.DataBinding.ConverterSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
		xmlns:local="clr-namespace:WpfTutorialSamples.DataBinding"
        Title="ConverterSample" Height="140" Width="250">
	<Window.Resources>
		<local:YesNoToBooleanConverter x:Key="YesNoToBooleanConverter" />
	</Window.Resources>
	<StackPanel Margin="10">
		<TextBox Name="txtValue" />
		<WrapPanel Margin="0,10">
			<TextBlock Text="Current value is: " />
			<TextBlock Text="{Binding ElementName=txtValue, Path=Text, Converter={StaticResource YesNoToBooleanConverter}}"></TextBlock>
		</WrapPanel>
		<CheckBox IsChecked="{Binding ElementName=txtValue, Path=Text, Converter={StaticResource YesNoToBooleanConverter}}" Content="Yes" />
	</StackPanel>
</Window>
using System;
using System.Windows;
using System.Windows.Data;

namespace WpfTutorialSamples.DataBinding
{
	public partial class ConverterSample : Window
	{
		public ConverterSample()
		{
			InitializeComponent();
		}
	}

	public class YesNoToBooleanConverter : IValueConverter
	{
		public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
		{
			switch(value.ToString().ToLower())
			{
				case "yes":
				case "oui":
					return true;
				case "no":
				case "non":
					return false;
			}
			return false;
		}

		public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
		{
			if(value is bool)
			{
				if((bool)value == true)
					return "yes";
				else
					return "no";
			}
			return "no";
		}
	}
}

El código detrás

Entonces, empecemos desde atrás y luego nos abrimos paso a través del ejemplo. Hemos implementado un conversor en el archivo de código llamado YesNoToBooleanConverter. Como advertimos, implementa únicamente los dos métodos necesarios, llamados Convert() y ConvertBack(). El método Convert() asume que recibe un string como entrada (el parámetro value) y lo convierte en un booleano verdadero o falso, con un valor por defecto de falso. Por diversión, agregué la posibilidad de realizar también la conversión del Francés.

El método ConvertBack() obviamente hace lo opuesto: asume un valor de entrada de tipo booleano y devuelve la palabra en inglés "yes" o "no" ("si" o "no") con valor por defecto de "no".

Te preguntarás sobre los parámetros adicionales de ambos métodos, pero no son necesarios en este ejemplo. Los usaremos en uno de los próximos capítulos, donde serán explicados.

XAML

En la sección XAML del programa, empezamos por declarar una instancia de nuestro conversor como un recurso de la ventana. Después tenemos un TextBox, un par de TextBlocks y un control CheckBox, y ahí es donde ocurre lo interesante: ligamos el valor del TextBox al TextBlock y al control CheckBox, y usando la propiedad Converter y nuestra referencia al conversor, jugamos con lo valores hacia un lado y el otro, dependiendo de que necesitamos.

Si intentas correr este ejemplo, podrás cambiar el valor en dos lugares: Escribiendo "yes" en el TextBox (o cualquier otro valor, si deseas un falso) o marcando el CheckBox. No importa lo que hagas, el cambio se verá reflejado en el otro control así como en el TextBlock.

Resumen

Esto fue un ejemplo de un conversor de valores simple, un poco más largo de lo necesario por motivos ilustrativos. En el siguiente capítulo nos meteremos en un ejemplo más avanzado, pero antes de que vayas y escribas tu propio conversor, deberías revisar si WPF ya incluye uno para eso. Al momento de escribir este artículo hay más de 20 conversores incorporados de los que puedes tomar ventaja, pero necesitas saber sus nombres. Encontré esta lista que te puede ser útil: http://stackoverflow.com/questions/505397/built-in-wpf-ivalueconverters


This article has been fully translated into the following languages: Is your preferred language not on the list? Click here to help us translate this article into your language!