Value Converters In WPF

Value converters are used to display values in a  more meaningful manner in WPF. Value converters are basically used with data bindings. With value converters, you can also localize data, create object based on underlying data, and even create objects and values that derive from multiple bound elements.

Probable Usages:

1. Converting a numeric code representing a job title into a string containing that job title:

  1. Product Owner
  2. Scrum Master
  3. Software Developer

2. Formatting Currency: Converting monetary values into currency-formatted string.

3. Formatting Dates: Formatting dates into various date formats e.g.14/04/2016, Thursday, April 14, 2016.

4. Converters to return objects: Storing references to images as string paths in database but loading and displaying images when viewing data.

In order to use Value Converters, one should first learn IValueConverter interface provided by PresentationFramework. It has two member methods:

  1. Convert: converts an input type to an output type. E.g. a numeric code (int type) to job title (string type).

  2. ConvertBack: It does the opposite of Convert.

Additionally, values converters are culture-aware. The parameters of the Convert and ConvertBack methods contain a reference to the Culture object to be used for the conversion. You can use the value of this parameter and use that information to return localized data.

How to use Value Converters:

In addition to implementing IValueConverter, you must decorate the class with the ValueConversion attribute, which specifies the source type and the target type for the converter. E.g. to convert a source type of Integer and a target type of String is shown here:

[ValueConversion(typeof(<SourceType>), typeof(<TargetType>))]

Example Code:

The example shows a TestConverter that takes int values and converts them into string.

  1. [ValueConversion(typeof(int), typeof(string))]  
  2. public class TestConverter: IValueConverter  
  3. {  
  4.     public object Convert(object value, Type targetType, object parameter, CultureInfo culture)  
  5.     {  
  6.         throw new NotImplementedException();  
  7.     }  
  8.     public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {  
  9.         throw new NotImplementedException();  
  10.     }  
  11. }  
In the example below, we have a lot of options to select. For the sake of simplicity, you can select only one at a time and see how it looks. The idea behind the example is to show how converters can be used to get the image and retrieve the image from center location and return image as an object which then further be bounded to an image source via data binding.

main

If no image is available in center location, the tool shows no preview available placeholder.

window

You can create a converter class in your project and provide its name space in the Xaml.

ImageConverter.cs
  1. [ValueConversion(typeof(string), typeof(BitmapImage))]  
  2. public class ImageConverter: IValueConverter   
  3. {  
  4.     public object Convert(object value, Type targetType, object parameter, CultureInfo culture)  
  5.     {  
  6.         try  
  7.         {  
  8.             string myPath = (string) value;  
  9.             Uri myURI = new Uri(myPath, UriKind.RelativeOrAbsolute);  
  10.             BitmapImage anImage = new BitmapImage(myURI);  
  11.             return anImage;  
  12.         } catch (Exception)  
  13.         {  
  14.             return new BitmapImage(new Uri("/Images/NoPreview.png", UriKind.RelativeOrAbsolute));  
  15.         }  
  16.     }  
  17.     public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {  
  18.         throw new NotImplementedException();  
  19.     }  
  20. }  
namespace in Xaml:
  1. xmlns:converter="clr-namespace:Certification.Converter"  
After declaring the namespace, you can create an object instance by adding it to one of resource collections and assign a key value under window resource to use it globally.
  1. <Window.Resources>  
  2.     <converter:ImageConverter x:Key="ImagePathConverter" />   
  3. </Window.Resources>  
After an object is created, you can set the converter property of your binding to it by referring to the resource.

Data binding:
  1. <Image Grid.Column="1" Height="140" Width="150" Source="{Binding Path=ImageSource,  
  2. RelativeSource={RelativeSource Mode=FindAncestor,   
  3. AncestorType={x:Type Window}},Mode=TwoWay,  
  4. UpdateSourceTrigger=PropertyChanged, Converter={StaticResource ImagePathConverter}}" />  
There is also MultiValueConverter that returns a converted value that results from multiple
fields. I shall explain in details about them in my next blog.