Silverlight cuenta con una característica completamente inigualable y bastante útil llamada Data Binding (Enlace de datos), esto quiere decir que yo puedo vincular datos entre elementos y poder desplegarlos o utilizarlos para cualquier acción sin la necesidad de utilizar código C#.
Contando con una herramienta tan útil, hay veces (como siempre) en donde vamos a necesitar de un “plus”, en donde queremos pasar ciertos valores de un tipo a elementos que están esperando otro valor, es aquí en donde entran en acción los Convertidores de Valores (IValueConverter), que en pocas palabras nos permiten obtener un valor y regresar uno completamente diferente, para que de esta forma, y de acuerdo al ejemplo que te mostraré, puedas ver como hacer que el nombre de un producto se ponga de color rojo de acuerdo a su existencia en almacén, o poder desplegar una u otra imagen dependiendo de una categoría.
Vamos iniciando con el proyecto, crea una nueva aplicación de Silverlight y en tu solución agrega dos folders, uno para tus clases y otro para las imágenes que vas a utilizar, en este último, puedes insertar dos imágenes de la forma que tu quieras, si quieres seguir de acuerdo a estos pasos, considera antes de continuar, descargar la solución de ejemplo al final de este artículo.
En la carpeta de clases, crea una cuatro nuevas clases, deja la solución de la siguiente forma para iniciar.
Ahora selecciona la clase Producto, en ella, simplemente vas a establecer las propiedades de tu producto, como dato adicional, vas a crearle un método constructor que pueda recibir datos y los asigne a las propiedades, de la siguiente manera.
namespace Convertidores { public class Producto { public string NombreProducto { get; set; } public decimal Precio { get; set; } public bool EsNuevo { get; set; } public int Existencia { get; set; } public Producto() { } public Producto(string nombre, decimal precio, bool esNuevo, int existencia) { NombreProducto = nombre; Precio = precio; EsNuevo = esNuevo; Existencia = existencia; } } } |
Después, en la clase de Productos, lo primero que debes hacer es asignarle una herencia a una lista de tipo “Producto”, crea un constructor y adentro de este vas a llamar la función de llenar datos, para que una lista tenga los elementos de prueba que necesitamos.
using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; namespace Convertidores { public class Productos : List { public Productos() { CrearColeccion(); } public ObservableCollection ListaDatos { get; set; } public ObservableCollection CrearColeccion() { ListaDatos = new ObservableCollection(); ListaDatos.Add(new Producto("Palomitas de maíz", 805, false, 25)); ListaDatos.Add(new Producto("Papas fritas", 605, true, 0)); ListaDatos.Add(new Producto("Paleta de caramelo", 6055, true, 12)); ListaDatos.Add(new Producto("Vasos para café", 1055, true, 5)); ListaDatos.Add(new Producto("Arizona de sandía", 2200, false, 15)); return ListaDatos; } } } |
Ya que tienes ambos elementos, podrías comenzar a trabajar con ellos, pero la idea principal del artículo viene ahora, abre tu clase ConvertidorExistencia.cs y reemplaza el código por lo que sigue.
using System; using System.Windows.Data; using System.Globalization; using System.Windows.Media; namespace Convertidores { public class ConvertidorExistencia : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { Brush colorLetra = new SolidColorBrush(Colors.Black); if (System.Convert.ToInt16(value) <= 5) { colorLetra = new SolidColorBrush(Colors.Red); } return colorLetra; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { return null; } } } |
Aquí la clase hereda de IValueConverter, debes incluir dos métodos llamados Convert y ConvertBack, como puedes ver, ambos requieren los mismos parámetros, la diferencia es que en el método Convert, por medio de un condicional, vas a evaluar una sentencia y de acuerdo a su resultado, obtendrás un color, el cual terminas regresando como valor.
En la clase ConvertidorNuevo.cs has lo siguiente.
using System; using System.Windows.Data; using System.Windows.Media.Imaging; using System.Globalization; namespace Convertidores { public class ConvertidorNuevo : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { BitmapImage imagen = new BitmapImage(); if (System.Convert.ToBoolean(value)) { imagen.UriSource = new Uri("../Imagenes/nuevo.png", UriKind.Relative); } else { imagen.UriSource = new Uri("../Imagenes/noNuevo.png", UriKind.Relative); } return imagen; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { return null; } } } |
La mecánica es exactamente la misma que en la clase anterior, la gran diferencia es que en esta clase no obtienes y manejas un color, sino un valor asignado a un BitmapImage por medio de una ruta.
Es importante mencionar que para cada conversión de datos que requieras hacer, debes tener tu propip convertidor, con esto en mente vamos a continuar.
En tu MainPage.xaml agrega una referencia al espacio de nombres de tu aplicación.
xmlns:local="clr-namespace:Convertidores" |
Ya con el espacio de nombres “local”, puedes colocar los tres elementos necesarios para tu aplicación en los recursos de tu control de usuario, estos elementos son tus dos clases de convertidores y tu clase de productos, para dejarlos de la siguiente forma.
<UserControl.Resources> <local:Productos x:Key="coleccionProductos"/> <local:ConvertidorNuevo x:Key="convertidorNuevo"/> <local:ConvertidorExistencia x:Key="convertidorExistencia"/> </UserControl.Resources> |
Ya con estos elementos en los recursos de tu control de usuario, coloca un ListBox dentro del Grid Principal
<ListBox Height="456" HorizontalAlignment="Left" Margin="12,12,0,0" VerticalAlignment="Top" Width="468"></ListBox> |
Adentro de este control, vas a insertar un DataTemplate y adentro del DataTemplate un contenedor con una imagen y dos TextBlock para dejar el XAML de la siguiente manera.
<DataTemplate> <StackPanel Orientation="Horizontal"> <Image Margin="6" Width="48" Height="47" /> <TextBlock Width="170" /> <TextBlock Width="150" /> </StackPanel> </DataTemplate> |
Es hora de ir con la parte interesante, el enlazado de datos. Primero comienzas con el ListBox. Te recuerdo que una parte muy importante es apoyarte en tus herramientas para escribir el siguiente código. Ve a las propiedades de tu ListBox, y presiona el botón cercano a la propiedad ItemsSource, para ver el siguiente menú.
En el menú que te aparece, ve a la sección “Source” y selecciona coleccionProductos.
Ve a la sección “Path” y selecciona ListaDatos.
El resultado de esta secuencia es la línea XAML siguiente.
<ListBox Height="456" HorizontalAlignment="Left" Margin="12,12,0,0" VerticalAlignment="Top" Width="468" ItemsSource="{Binding Source={StaticResource coleccionProductos}, Path=ListaDatos}"> |
Para la imagen, primero debes escoger el contexto que usarás.
Después la propiedad a enlazar, la cual es EsNuevo.
Y por último el convertidor, aquí es en donde invocarás al convertidor que creaste en segundo lugar, ConvertidorNuevo.
Realiza la misma secuencia con el texto que te dará el nombre del producto y cambiará de color de acuerdo a la existencia, al terminar el XAML completo de tu ListBox es el siguiente.
<ListBox Height="456" HorizontalAlignment="Left" Margin="12,12,0,0" VerticalAlignment="Top" Width="468" ItemsSource="{Binding Source={StaticResource coleccionProductos}, Path=ListaDatos}"> <ListBox.ItemTemplate> <DataTemplate> <StackPanel Orientation="Horizontal" ToolTipService.ToolTip="{Binding Path=Existencia, StringFormat='Existencia: {0}'}"> <Image Margin="6" Width="48" Height="47" Source="{Binding Path=EsNuevo, Converter={StaticResource convertidorNuevo}}" /> <TextBlock Width="170" Text="{Binding Path=NombreProducto}" Foreground="{Binding Path=Existencia, Converter={StaticResource convertidorExistencia}}" /> <TextBlock Width="150" Text="{Binding Path=Precio, StringFormat=c}"/> </StackPanel> </DataTemplate> </ListBox.ItemTemplate> </ListBox> |
Así de sencillo es como puedes utilizar Convertidores de valores para adaptar una propiedas a otra.
Puedes descargar el código aquí.