Microsoft Dot Net Master

Microsoft Dot Net Master
Microsoft Dot Net Master

Thursday, July 19, 2012

ValueConverters

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; 
    }            
}

No comments:

Post a Comment