Using Value Converters in Silverlight

When you start to bind data in Silverlight (or WPF for that matter) you will most likely have data that is in one format that you may need to convert to another format. For example if you have a decimal number (price) that is 19.95, you would want to display it as $19.95. Of course you can use a normal .NET format string to accomplish this, but you could also write some code to convert the decimal number 19.95 to a string with the dollar sign in front of it “$19.95”.

In the sample that you are going to read about, you have a Boolean value of true or false, and based on this true or false value you will return one bitmap image or another bitmap image. To accomplish this you need to tell Silverlight that instead of displaying the Boolean value that it should pass the Boolean value to a method in a class you create and have that method return a bitmap image back and to display that bitmap (Figure 1 and Figure 2).

Figure 1
Figure 1: A Value Converter class transforms data to another type

Figure 2
Figure 2: Sample of using Value Converter

The Product Class
For this example, I will be using a simple Product class with three properties, and a collection class of Product objects using the Generic List class. You can create this sample by creating a Product class as shown in the following code:

public class Product {

  public Product() { }

  public Product(string name, decimal price,
                 bool onSpecial)  {
    this.ProductName = name;
    this.Price = price;
    this.IsOnSpecial = onSpecial;
  }

  public string ProductName { get; set; }
  public decimal Price { get; set; }
  public bool IsOnSpecial { get; set; }
}

Create a collection class that initializes a property called DataCollection with some sample data as shown in the code below:

public class Products : List<Product> {
  public Products() {
    InitCollection();
  }

  public List<Product> DataCollection { get; set; }

  List<Product> InitCollection() {
    DataCollection = new List<Product>();

    DataCollection.Add(new Product(3,
      "PDSA .NET Productivity Framework"), 5000, true));
    DataCollection.Add(new Product(1,
      "Haystack Code Generator for .NET", 799, true));
    DataCollection.Add(new Product(1,
      "Fundamentals of .NET eBook", 20, false));

    // MORE PRODUCTS HERE – REMOVED FOR BREVITY

    return DataCollection;
  }
}

You are going to need a “blank” image to display next to those products that are not on special. You will also need an “OnSpecial” image for those that are on special. Included in the sample project are two .jpg images that you can use for these two images. In the sample project these two images are contained in the \Images folder in the Silverlight project.

The OnSpecialConverter Value Converter Class
As mentioned at the beginning of this article you need to create a class with a method to convert a Boolean value to a Bitmap image. This class must implement a special interface called IValueConverter. This interface only has two methods; Convert() and ConvertBack(). Most times you will only implement the Convert() method. Below is the C# class called “OnSpecialConverter” that implements the two methods Convert and ConvertBack.

public class OnSpecialConverter : IValueConverter {
  public object Convert(object value,
                        System.Type targetType,
                        object parameter,
                        CultureInfo culture)
  {
    BitmapImage img = new BitmapImage();

    if (System.Convert.ToBoolean(value)) {
      img.UriSource = new Uri("../Images/OnSpecial.jpg",
                               UriKind.Relative);
    }
    else {
      img.UriSource = new Uri("../Images/Blank.jpg",
                               UriKind.Relative);
    }

    return img;
  }

  public object ConvertBack(object value,
                            System.Type targetType,
                            object parameter,
                            CultureInfo culture)
  {
    return null;
  }
}

In the Convert method the main parameter you will be working with is the “value” parameter. This is the value that was bound to in the XAML. In this example that is the IsOnSpecial value from the Product class. So, the value “True” or “False” is passed into the Convert method in the “value” parameter. Your job is to check this value parameter and if the value is “true”, create a BitmapImage object with the “OnSpecial.jpg” image in it that you return from this method. If the value is “false”, then you create a BitmapImage object with the “Blank.jpg” image in it that you return from this method.

Namespaces and Resources
Now that you have this class created you will have your Silverlight user control create an instance of that class. To do this, you first add the namespace where this class was created. At the top of your user control you add a xmlns tag as shown below.

xmlns:local="clr-namespace:SLValueConverter"

The 'local' is any name you want to create. VS.NET will then display a list of namespaces that are available in your Silverlight project. In the example above the name of the project is “SLValueConverter”.

Next you create a UserControl.Resources section in your XAML where you can create an instance of both the Products collection class and the value converter class.

<UserControl.Resources>
  <local:Products x:Key="productCollection" />
  <local:OnSpecialConverter x:Key="specialConvert" />
</UserControl.Resources>

The code above creates an instance of each class when the Silverlight user control is created. These two classes can now be used anywhere in this user control.

The List Box Control
To create the list box shown in Figure 2, you will need to bind a <ListBox> control to the Products class created in the Resources section. In the DataTemplate of the list box you create an <Image> control that uses the OnSpecialConverter class. Look at the XAML below for the bindings.

<ListBox x:Name="lstData"
         ItemsSource="{Binding
              Source={StaticResource productCollection},
                      Path=DataCollection}">
  <ListBox.ItemTemplate>
    <DataTemplate>
      <StackPanel Orientation="Horizontal">
        <TextBlock Width="250"
                    Text="{Binding Path=ProductName}" />
        <TextBlock Width="100"
                    Text="{Binding Path=Price,
                                   StringFormat=c}" />
        <Image Margin="8"
               Source="{Binding IsOnSpecial,
                 Converter={StaticResource specialConvert}}"
                Width="100"
                Height="100" />
      </StackPanel>
    </DataTemplate>
  </ListBox.ItemTemplate>
</ListBox>

Notice the <Image> element where the Source property binds to the IsOnSpecial property of the Product class. As you remember, the IsOnSpecial is a Boolean property in the Product class. You want to display one of two images in this image control based on the true or false value in the IsOnSpecial property. So, you need to tell Silverlight that you want it to pass the Boolean value (IsOnSpecial) to the converter class’ Convert method and that method will return an image back that the <Image> control can then display.

Summary
In this blog entry you learned how to use a Value Converter class to take data that is in one format and convert it to another format prior to displaying that value in a XAML control. You can create, and you will, as many value converters as you need that convert any data type to any other data type. You could also use value converter classes simply to do formatting of data as well.

NOTE: You can download the complete sample code (in both VB and C#) at my website. http://www.pdsa.com/downloads. Choose Tips & Tricks, then "Using Value Converters in Silverlight" from the drop-down.

Good Luck with your Coding,
Paul Sheriff

** SPECIAL OFFER FOR MY BLOG READERS **
Visit http://www.pdsa.com/Event/Blog for a free videos on Silverlight entitled Silverlight XAML for the Complete Novice - Part 1.

Past Blog Content

Blog Archive

6 Comments

  • Excellent tutorial! Exactly what I was trying to do. Thank you!

  • Question: I have a listbox control. It is bound to data in a database, not an object like here. I have the URL for an image stored in each of the records returned from the database. I need to display that in the list box.

    does not work by itself. The URL stored in the database looks something like this: "/images/1_0.jpg"

    How do I get the image to display?

  • Robert,

    You will need to use a converter for this as well. Your converter will have to take the path and convert it to a bitmap. You then return that bitmap for the Source attribute in the Image control.

    public object Convert(object value, System.Type targetType,
    object parameter,
    System.Globalization.CultureInfo culture)
    {
    BitmapImage img = new BitmapImage();

    if (value != null)
    {
    if (value.ToString() != string.Empty)
    {
    img.UriSource = new Uri(value.ToString(), UriKind.Relative);
    }
    }

    return img;
    }

  • Thanks for the tutorial! Really helped me and saved me a lot of head bashing :)

  • Nice one.. easy to understand and implement. it was a great help for me.

  • Hi,
    I have two column with image and drop down. Is there any possible way to change the image by changing the drop down inside the grid?

Comments have been disabled for this content.