« Knight Rider, the Movie? [sigh] | Main | Google Web Toolkit Released to little fanfair ... »

IValueConverter and WPF

It's likely at some point you'll encounter a situation where you want to do some data binding in WPF. However, the data you're binding to may not be in the format you actually want to display to the end user. WPF has a relatively simple solution to this problem, value converters.

In the following example, I wanted to have a slider that as I moved the slider would increase the date on the image displayed. The slider's native data type is a double. I wanted to display the date as Day of the Week, Date.

As I use the slider, I'd like it to look more like this:

The date should update immediately as the slider value changes.

There's no simple binding that does everything. There might be a completely XAML based solution for this, but obscure XAML isn't the best for long term maintenance, no matter how cool it was that it could be done all in XAML. So, instead I present the value converter.

Here's the label I'm using:

<Label VerticalAlignment="Top" HorizontalAlignment="Center"

FontFamily="Tahoma"

Foreground="White"

Content="{Binding Value, ElementName=DateSlider, Mode=OneWay, Converter={StaticResource SillyDateConvert}}"

FontSize="10pt"

FontWeight="Bold"

SnapsToDevicePixels="True" >

<Label.BitmapEffect>

<OuterGlowBitmapEffect GlowColor="Black" GlowSize="2" Opacity="1" />

</Label.BitmapEffect>

</Label>

The important attribute to pay particular attention to is the Content attribute of the label. Specifically, the Converter of the Binding. Converter={StaticResource SillyDateConvert} refers to a resource I declared in the Resources:

<wp:SillyDateConverter x:Key="SillyDateConvert" />

The namespace, wp, is declared in the root element as

xmlns:wp="clr-namespace:ShowValueConverter"

In a separate code file, I've created a class, called the SillyDateConverter (C# here):

[ValueConversion(typeof(double), typeof(String))]

public class SillyDateConverter : IValueConverter

{

public object Convert(object value, Type targetType,

object parameter,

System.Globalization.CultureInfo culture)

{

DateTime dt = DateTime.Now;

dt = dt.AddDays( (double) value);

return dt.ToString("D");

}

public object ConvertBack(object value,

Type targetType,

object parameter,

System.Globalization.CultureInfo culture)

{

throw new Exception("The method or operation is not implemented.");

}

}

Since my code only does one way binding, I've left the default exception in the ConvertBack method. In the Convert method, I use the bound value from the slider (passed as value), to construct and then return the formatted date.

As a final example, I added another converter to round a double. For some reason, the slider doesn't quite operate the way I'd expect. Even though small change is set to 1, it allows decimals to creep in if I use the mouse.

Here is the sample project (zip): ShowValueConverter.zip (21 KB)

Built and tested with the Feb/March 2006 CTP of WPF.

Help support my web site by searching and buying through Amazon.com (in assocation with Amazon.com).