Bookmark and Share Share...    Subscribe to this feed Feed   About Christian Moser  


ValueConverters

Introduction

If you want to databind two properties that have incompatible types, you need a piece of code in between, that converts the value from source to target type and back. This piece of code is called ValueConverter. A value converter is a class, that implements the simple interface IValueConverter with the two methods object Convert(object value) and object ConvertBack(object value).

How to implement a ValueConverter

WPF already provides a few value converts, but you will soon need to implement your own converts. To do this, add a class to your project and call it [SourceType]To[TargetType]Converter. This is a common naming for value converters. Make it public and implement the IValueConverter interface. That's all you need to do.

 
public class BoolToVisibilityConverter : IValueConverter
{
    public object Convert(object value, Type targetType, 
        object parameter, CultureInfo culture)
    {
        // Do the conversion from bool to visibility
    }
 
    public object ConvertBack(object value, Type targetType, 
        object parameter, CultureInfo culture)
    {
        // Do the conversion from visibility to bool
    }
}
 
 

How to use 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="VirtualControlDemo.Window1"
    ...
    xmlns:l="clr-namespace:VirtualControlDemo"
    ...>
    <Window.Resources>
        <l:BoolToVisibilityConverter x:Key="converter" />
    </Window.Resources>
    <Grid>
        <Button Visibility="{Binding HasFunction, 
            Converter={StaticResource converter}}" />
    </Grid>
</Window>
 
 

Simplify the usage of ValueConvers

If you want to use a normal ValueConverter in XAML, you have to add an instance of it to the resources and reference it by using a key. This is cumbersome, because and the key is typically just the name of the converter.

A simple and cool trick is to derive value converters from MarkupExtension. This way you can create and use it in the binding like this: Text={Binding Time, Converter={x:MyConverter}}, and that is quite cool!

 
public abstract class BaseConverter : MarkupExtension
{
    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        return this;
    }
}
 
 

StringFormat Converter

The StringFormatConverter is a useful converter to control the format of an implicit string conversion of an object (e.g. if you bind a DateTime to a TextBlock ).

 
[ValueConversion(typeof(object), typeof(string))]    
public class StringFormatConverter : BaseConverter, IValueConverter    
{        
    public object Convert(object value, Type targetType, object parameter,
                      System.Globalization.CultureInfo culture)        
    {            
        string format = parameter as string;
        if (!string.IsNullOrEmpty(format))
        {                
             return string.Format(culture, format, value);
        }
        else           
        {                
            return value.ToString();
    }
 
    public object ConvertBack(object value, Type targetType, object parameter,
                    System.Globalization.CultureInfo culture)
    {
        return null; 
    }            
}
 
 
 




Last modified: 2010-02-19 07:56:23
Copyright (c) by Christian Moser, 2011.

 Comments on this article

Show all comments
Anon
Commented on 6.November 2009
Thanks for these cool examples. It would help a lot if you would add the namespaces one has to add in order to use your examples. Would save a lot of time
Farzad
Commented on 12.November 2009
Great article

just a typo:
valueConverter instead of ValueConvers
Ralph
Commented on 25.November 2009
Maybe useful to mention how to use the parameter:

ToolTip="{Binding Path=Hostname, Converter={x:StringFormatConverter}, ConverterParameter=Connected to {0}}"

correct?
Gishu
Commented on 25.March 2010
It would be helpful to mention that this converter already exists in System.Windows.Controls namespace in the Presentation assembly and can be directly used in XAML as
<BooleanToVisibilityConverter x:Key="BoolToVisibilityConverter"/>

The fact that you used this as an example kind of lead me to believe that it doesn't exist as part of the framework. It was the converter naming convention (that was new to me) helped me to find it in the Object browser window.

Great post. Thanks!
Patrik
Commented on 22.June 2010
How do I use the MarkupExtension, when the Converter is in another NameSpace than the consumer code?

Thanks for sharing the Converter!
Bill
Commented on 8.July 2010
owsome
Bill1
Commented on 15.April 2011
How to use Validators along with converters?
Jorge
Commented on 27.June 2011
Esto esta bien cabron

Name
E-Mail (optional)
Comment