Los convertidores de valor en Windows Presentation Foundation (WPF) son una herramienta fundamental para adaptar datos de un tipo a otro, permitiendo una representación visual flexible en la interfaz de usuario. Al implementar la interfaz IValueConverter, es posible transformar los datos del modelo de vista (ViewModel) antes de que se muestren en la vista (View), o viceversa.
1. Implementando un Convertidor de Booleanos a Símbolos
Un caso de uso común es mostrar un símbolo diferente, como una flecha, basándose en un valor booleano. Por ejemplo, si un valor numérico está creciendo, se podría mostrar una flecha hacia arriba; si está decreciendo, una flecha hacia abajo.
Para ello, se define una clase que implemente IValueConverter. La interfaz requiere la implementación de dos métodos: Convert, que maneja la conversión de origen a destino (ViewModel a View), y ConvertBack, para la conversión inversa.
using System;
using System.Globalization;
using System.Windows.Data;
namespace MiAplicacion.Convertidores
{
/// <summary>
/// Convierte un valor booleano en un símbolo de flecha (▲/▼).
/// </summary>
public class BooleanoAFlechaConverter : IValueConverter
{
/// <summary>
/// Convierte un booleano a un símbolo de flecha.
/// </summary>
/// <param name="valor">El valor booleano a convertir.</param>
/// <param name="tipoObjetivo">El tipo al que se desea convertir.</param>
/// <param name="parametro">Parámetro de convertidor opcional.</param>
/// <param name="cultura">Información de cultura.</param>
/// <returns>Un símbolo de flecha (▲ para verdadero, ▼ para falso).</returns>
public object Convert(object valor, Type tipoObjetivo, object parametro, CultureInfo cultura)
{
if (valor is bool esPositivo)
{
return esPositivo ? "▲" : "▼";
}
return ""; // Retorna cadena vacía si el valor no es booleano
}
/// <summary>
/// No implementado.
/// </summary>
public object ConvertBack(object valor, Type tipoObjetivo, object parametro, CultureInfo cultura)
{
throw new NotImplementedException("La conversión inversa no está soportada para BooleanoAFlechaConverter.");
}
}
}
2. Usando Convertidores en XAML
Para utilizar un convertidor, primero se debe declarar su namespace en el archivo XAML y luego instanciarlo como un recurso. A continuación, se puede aplicar a cualquier enlace de datos (Binding) utilizando la propiedad Converter.
2.1. Declarar el Namespace
Añade una declaración de namespace en la raíz de tu archivo XAML (por ejemplo, UserControl o Window):
xmlns:convertidores="clr-namespace:MiAplicacion.Convertidores"
2.2. Instnaciar el Convertidor como un Recurso
Dentro de la sección Resources de tu control o aplicación, instancia el convertidor asignándole una clave:
<UserControl.Resources>
<convertidores:BooleanoAFlechaConverter x:Key="FlechaBooleanaConv"/>
</UserControl.Resources>
2.3. Aplicar el Convertidor en el Enlace de Datos
Ahora, puedes usar el convertidor en un TextBlock para mostrar el símbolo correspondiente:
<TextBlock Text="{Binding EsCreciente, Converter={StaticResource FlechaBooleanaConv}}"
FontSize="16" FontWeight="Bold" VerticalAlignment="Center" Margin="5,0,0,0"/>
3. Personalizando Colores de Celdas en DataGrid
Otro escenario común es cambiar el color de fondo o de texto de una celda en un DataGrid basándose en su contenido. Por ejemplo, una celda podría mostrarse en rojo si contiene un estado de "Error" y en un color predeterminado si es "Éxito".
3.1. Convertidor de Estado a Pincel
Crea una nueva clase convertidora que mapee valores de cadena a objetos Brush (pincelse de color).
using System;
using System.Globalization;
using System.Windows.Data;
using System.Windows.Media;
namespace MiAplicacion.Convertidores
{
/// <summary>
/// Convierte un valor de cadena de estado en un color de pincel.
/// </summary>
public class EstadoAPincelColorConverter : IValueConverter
{
/// <summary>
/// Convierte una cadena de estado a un objeto Brush.
/// Si el estado es "ERROR" (insensible a mayúsculas/minúsculas), retorna un pincel rojo.
/// De lo contrario, retorna un pincel transparente (o null para el predeterminado).
/// </summary>
/// <param name="valor">El valor de estado (string) a convertir.</param>
/// <param name="tipoObjetivo">El tipo al que se desea convertir (normalmente Brush).</param>
/// <param name="parametro">Parámetro opcional para definir el estado de éxito (por defecto "ERROR").</param>
/// <param name="cultura">Información de cultura.</param>
/// <returns>Un objeto Brush.</returns>
public object Convert(object valor, Type tipoObjetivo, object parametro, CultureInfo cultura)
{
if (valor is string estadoStr)
{
string estadoProblema = (parametro as string)?.ToUpperInvariant() ?? "ERROR";
if (estadoStr.ToUpperInvariant() == estadoProblema)
{
return Brushes.Red;
}
else
{
return Brushes.Transparent; // Usar color de fondo predeterminado si no es un error
}
}
return Brushes.Transparent; // Valor predeterminado si el valor no es una cadena
}
/// <summary>
/// No implementado.
/// </summary>
public object ConvertBack(object valor, Type tipoObjetivo, object parametro, CultureInfo cultura)
{
return Binding.DoNothing; // Indica que no se debe transferir el valor al origen
}
}
}
3.2. Aplicar el Convertidor en DataGridTemplateColumn
Para aplicar un estilo condicional a una celda del DataGrid, es común usar DataGridTemplateColumn. Dentro de su CellTemplate, se coloca un TextBlock u otro control visual cuyo fondo o primer plano se enlaza a la propiedad deseada utilizando el convertidor.
Primero, declara el nuevo convertidor en los recursos:
<UserControl.Resources>
<convertidores:BooleanoAFlechaConverter x:Key="FlechaBooleanaConv"/>
<convertidores:EstadoAPincelColorConverter x:Key="EstadoACeldaColorConv"/>
</UserControl.Resources>
Luego, usa el convertidor en la columna del DataGrid:
<DataGrid ItemsSource="{Binding ElementosDeDatos}" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="ID" Binding="{Binding ID}" Width="Auto"/>
<DataGridTextColumn Header="Descripción" Binding="{Binding Descripcion}" Width="*"/>
<DataGridTemplateColumn Header="Estado Operacional" Width="Auto">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding EstadoOperacional}"
Background="{Binding Path=EstadoOperacional, Converter={StaticResource EstadoACeldaColorConv}, ConverterParameter='FALLO'}"
Padding="4" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
En este ejemplo, la columna "Estado Operacional" mostrará el texto del estado, y si el valor de EstadoOperacional es "FALLO" (o el valor especificado en ConverterParameter), el fondo de la celda se pondrá en rojo.