Category Archives: .NET Attributes

Introduction to Value Converters – Data Conversion

One of the nicest things that you can do with data binding in WPF is that you can convert the data as you pull it from the data source. The source data might not be compatible with what the target object property is expecting(type). so if you want to bind two properties that have incompatible types, you need some translation mechanism between your binding source and destination, that converts the value from source to target type and back. This mechanism is called ValueConverter. Basically, we will implement a value converter class, that implements the interface IValueConverter with the two methods Convert and ConvertBack. WPF already includes some value converters but in most cases you will need to write your own by implementing the IValueConverter interface.

Also, sometimes we need to apply custom logic to the Source object property data so that the data is meaningful to our bound target property. The custom logic may be in the form of a custom converter (if default type conversion does not exist). Well, to say it in simple words it is a Converter that converts value based on input as Source and provides output as Target as shown in the following figure.

image

As you can see from the above image we have both way arrows in between Source and Target. That means: the value converter not only designed to take input from the target and modify the source, it also works when source data is updated on target. As we discussed in the beginning that the Source and Target can convert each other so that’s why we have two methods defined. Convert would do conversion from Source -> Target and ConvertBack would do conversion from Target –> Source.

The following Figure1 shows the hierarchy of important classes in the Framework.

image

Figure 1: Hierarchy of important framework classes derived from Object.

image

Figure 2: Hierarchy of Binding classes

Following is the sample code to convert a (Source Property) double to an int(Target Property). Lets say I have a class that contains a double property and in my UI one of the controls is expecting an integer value. In the following example, we will bind the Slider control Value property (which is double type) to the Textbox Text property(int type;We just want to display integers). So how do we bind them together?

Implementing a IValueConverter:

Add a class to your project and call it CustomDoubletoIntegerDataConverter.Make it public and implement the IValueConverter interface. In the Convert function, value contains the Source property value and it returns the value to the Target object property. Implement the Convert function, which will be used by the Binding object, sends the source property value to the Convert function and assigns the returned value to the target property.

  1.     [ValueConversion(typeof(double), typeof(int))]
  2.     public class CustomDoubletoIntegerDataConverter : IValueConverter
  3.     {
  4.         public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
  5.         {
  6.             return (int) (double)value ;
  7.         }
  8.  
  9.         public object ConvertBack(object value, Type targettype, object parameter, System.Globalization.CultureInfo culture)
  10.         {
  11.             throw new NotSupportedException( "Implementation not supported" );
  12.         }
  13.  
  14.     }

Download the  Source Code from here.

The first thing you might notice is the ValueConversion attribute. This is not actually required(optional), but it helps tell developer tools what type is going to be converted to what other type. The value, targetType, and culture are all automatically passed in by WPF’s binding engine. The parameter is an optional object.

Using a ValueConverter in XAML:

First thing you need to do is to map the namespace of your converter to a XAML namespace. Then you can create an instance of a value converter in the resources of the view and give it a name. Then you can reference it by using {StaticResource}

<Window x:Class="DataConversion.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml&quot;
        Title="MainWindow" Height="350" Width="525"
        xmlns:mylocalXAMLnamespace="clr-namespace:DataConversion">
    <StackPanel>
        <StackPanel.Resources>
            <mylocalXAMLnamespace:CustomDoubletoIntegerDataConverter x:Key="XAML_Instanceof_CustomDoubletoIntegerDataConverter_Class"></mylocalXAMLnamespace:CustomDoubletoIntegerDataConverter>
        </StackPanel.Resources>
        <Slider Name="Slider1"> </Slider>
        <TextBlock Name="TextBlock1" Text="{Binding ElementName=Slider1, Path=Value, Converter={StaticResource XAML_Instanceof_CustomDoubletoIntegerDataConverter_Class}}"></TextBlock>
    </StackPanel>
</Window>

 

Following is the output of binding without and with Value Converters.image

When you get the error "No constructor for type ‘…’ has 0 parameters.", you need to add an default constructor to your converter, even it’s not needed. Just for the WPF designer.

you can derive your value converter from MarkupExtension and return its own instance (this) in the ProvideValue override. So you can use it directly without referencing it from the resources, which we will see in another post.

We will also discuss amount Multi Binding and Multi Value converters in the another post.

Download the  Source Code from here.

"Let your life mean something. Become an inspiration to others so that they may try to do more and to become more than they are today." – Thomas D. Willhite

Advertisements