Data Binding with Value Converters

Keep your code intelligent and efficient

Dan Wahlin

October 30, 2009

9 Min Read
ITPro Today logo

Silverlight 3 provides a flexible way to bind datato controls using a simple yet powerful syntax. Although you can control whatdata is bound to a control by changing the data before it's bound, there willbe times when you need to massage the data at the user interface level so thatit displays in a specific format. For example, you may bind a DateTime objectto a TextBlock control and require that only the date is shown, as opposed tothe date and time. In other situations, you may need to convert a Booleanproperty value into a Visibility enumeration value to show or hide a control. Silverlightcontains several different value converters that can make adjustments, such asconvert the name of a color into a SolidColorBrush.

I'll introduce you to the concept of valueconverters and explain how they can be created, referenced, and used in aSilverlight application. By using value converters properly, you can simplifythe data binding process, reduce code, and ease future maintenance of yourSilverlight applications.

Why We Need Value Converters

Data comes in all shapes and sizes, and sometimesthe data you're working with needs to be changed because it's bound to acontrol in the user interface. Fortunately, Silverlight provides built-infunctionality for modifying data as it goes into a control and even as it goesout of a control, back to the bound object. So why do you need valueconverters? Let's look at a simple example to get started.

Figure 1 shows several TextBlock controls that arebound to customer data. The birthday TextBlock displays the date, but alsoshows the default time of midnight since a valid time wasn't originally definedin the source data. While there may be times when you need the time to show,it's obviously not something normally shown for a birthday.

Figure 1: Default TextBlock display

By creating a value converter, you can control howthe DateTime value is displayed and even apply different types of formats tothe data when needed. Figure 2 shows how the data binding can be changed byadding a value converter into the mix. You can see that the time is no longershown, as is standard with a birthday value.

Figure 2. TextBlock after using value converters

Creating a Value Converter

Creating a value converter is a surprisingly simpleprocess in Silverlight. In fact, all of the shell code required can begenerated automatically using Visual Studio 2008. To get started, you'll firstneed to create a class within a Silverlight application or class libraryproject. Value converters rely upon an interface called IValueConverter, whichis located in the System.Windows.Data namespace, so you'll need to add areference to that namespace in your code. Once that's done, the value converterclass can implement the IValueConverter interface.

IValueConverter defines two members, includingConvert and ConvertBack. Convert is used to modify data as it's bound from thesource object to the control. ConvertBack works the other way. As a userchanges data in a control such as a TextBox, the data can be converted back tothe original data type in the source object by using ConvertBack. OnceIValueConverter is added to your class, you can right-click it in Visual Studioand select Implement Interface from the menu to automatically fill in theConvert and ConvertBack methods. If you're using Visual Basic, you can simplyhit enter after the interface name to accomplish the same thing.

Both Convert and ConvertBack accept the sameparameters, including the data being bound, the type of the data being bound,any parameter data passed in that can be used in the data conversion process,and the target culture that the entire process is running under (English,Spanish, French, etc.). Here's what the method signatures look like:

object Convert(object value, Type targetType,object parameter, CultureInfo culture);object ConvertBack(object value, Type targetType,object parameter, CultureInfo culture);

In many situations, you only need to worry aboutthe actual data being bound (the value parameter) and can use built-in .NETdata conversion methods to get the job done. Other times, you may need tointegrate a parameter into the process to allow more control over how the datais modified by the value converter. Figure 3 shows a simple value converternamed DateConverter that can be used to convert DateTime values into variousdate and time formats.

Looking at the Convert method in Figure 3, you cansee that it converts the value passed in into a DateTime object. It then usesthe parameter value passed, as well as the language culture, to format thevalue being bound and return it. By allowing a parameter to be passed into theDateConverter class, it can be used to return several different types ofdate/time formats.

The ConvertBack method converts the value passedinto a string and attempts to convert the string back into a DateTime objectusing the standard DateTime.TryParse method. If the value can't be converted, avalue of DependencyProperty.UnsetValue is returned so that the target propertyisn't updated. It's important to note that any exceptions raised within customvalue converter objects will trigger a runtime exception in Silverlight.

Using a Value Converter

To use a value converter, you'll need to first add areference to the class's namespace and assembly and then define it within theresources section of either the current page/user control (in App.xaml or in amerged dictionary XAML file). If you'll be using a specific value converterthroughout an application, it's recommended that you define it in the App.xamlfile or within a merged resource dictionary file.

An example of defining a value converter namespacein a user control is shown next. Note that the value converter class is in thesame project as the Silverlight application so no assembly reference isrequired.

(Note: Some code lines in text wrap to several lines because of spaceconstraints.)

 ...

Once the value converter namespace is defined, youcan reference the class using XAML:

Looking at the previous code, you can see that thesyntax is much like what you'd do in ASP.NET when defining user controls,although a key is defined instead of an id. The key can be used in any databinding expression to force data to be routed through the value converterobject.
Once the value converter is defined in a resources section within theSilverlight application, you can use it within data binding expressions. Thisis done by using the Converter and ConverterParameter properties as shown next:

Notice that the Converter property references theDateConverter key defined earlier by using the StaticResource keyword. The typeof date format to use when converting and formatting the data that's beingbound is passed using the ConverterParameter property. In this case, the"d" parameter value tells the Convert method within the valueconverter object to only return a date string without the time. Other date/timeformat codes can be passed in using ConverterParameter as needed.

When a TwoWay binding is set up, both the Convertand ConvertBack methods will be called in the value converter object. Here's anexample of using DateConverter with a TwoWay binding:


Examples of Value Converters

I find myself using value converters quite often inSilverlight applications, given that they can minimize the amount of customcode that has to be written and simplify maintenance down the road. Here are afew of the converters I use in projects.

BoolToVisibilityConverter. TheBoolToVisibilityConverter is a value converter that's used to show and hidedifferent objects within a page or user control. The object that UI controlsare bound to (oftentimes referred to as the ViewModel class) can define Booleanproperties such as IsButtonVisible. The BoolToVisibilityConverter handlesconverting true and false property values into Visibility.Visible andVisibility.Collapsed, as appropriate. Figure 4 shows an example of thisconverter.

NullToVisibilityConverter. TheNullToVisibilityConverter handles converting null values into Visibilityenumeration members. It's useful when you bind a property to a control and theproperty can be null. Figure 5 shows the NullToVisibilityConverter.

ListCountVisibilityConverter. TheListCountVisibilityConverter handles showing or hiding item controls such asListBox when a specific number of items are bound to the ItemsSource property. Forexample, if only one item is available in a collection you may not want aListBox to show while two or more items should cause the control to be shown. Thisvalue converter allows you to pass in the cut-off number that determines whento show or hide a control and the Covert method handles returning the properVisibility enumeration member. Figure 6 shows the code for theListCountVisibilityConverter.

Code Intelligently and Efficiently

You've seen how value converters can manipulate dataas it goes in and out of controls. By using value converters, you can minimizethe amount of custom code that would normally have to be written to change yourdata. They're an important addition to your arsenal as a Silverlight developer.

Codeaccompanying this article is available for download.

Figure 3:DateConverter value converter

using System;using System.Windows.Data;namespace DataBinding{public class DateConverter : IValueConverter{#region IValueConverter Members//Called when binding from an object property to a control propertypublic object Convert(object value, Type targetType,object parameter, System.Globalization.CultureInfo culture){DateTime dt = (DateTime)value;return dt.ToString((string)parameter, culture);}//Called with two-way data binding as value is pulled out of control//and put back into the propertypublic object ConvertBack(object value, Type targetType,object parameter, System.Globalization.CultureInfo culture){string val = (string)value;DateTime outDate;if (DateTime.TryParse(val, culture, DateTimeStyles.None,out outDate)){return outDate;}return DependencyProperty.UnsetValue;}#endregion}}


Figure 4:BoolToVisibilityConverter value converter

public class BoolToVisibilityConverter : IValueConverter{#region IValueConverter Memberspublic object Convert(object value, Type targetType,object parameter, System.Globalization.CultureInfo culture){if (parameter == null){return ((bool)value == true) ? Visibility.Visible :Visibility.Collapsed;}else if (parameter.ToString() == "Inverse"){return ((bool)value == true) ? Visibility.Collapsed :Visibility.Visible;}return false;}public object ConvertBack(object value, Type targetType,object parameter, System.Globalization.CultureInfo culture){throw new NotImplementedException();}#endregion}


Figure 5:NullToVisibilityConverter value converter

public class NullToVisibilityConverter : IValueConverter{#region IValueConverter Memberspublic object Convert(object value, Type targetType,object parameter, System.Globalization.CultureInfo culture){if (parameter == null) //Not invert parameter passed{return (value == null) ? Visibility.Collapsed :Visibility.Visible;}else if (parameter.ToString() == "Inverse"){return (value == null) ? Visibility.Visible :Visibility.Collapsed;}return Visibility.Collapsed;}public object ConvertBack(object value, Type targetType,object parameter, System.Globalization.CultureInfo culture){throw new NotImplementedException();}#endregion}


Figure 6:ListCountVisibilityConverter value converter

public class ListCountVisibilityConverter : IValueConverter{#region IValueConverter Memberspublic object Convert(object value, Type targetType,object parameter, System.Globalization.CultureInfo culture){if (value != null){IList list = value as IList;if (list != null){int minCount = int.Parse(parameter.ToString());return (list.Count > minCount) ? Visibility.Visible :Visibility.Collapsed;}}return Visibility.Collapsed;}public object ConvertBack(object value, Type targetType,object parameter, System.Globalization.CultureInfo culture){throw new NotImplementedException();}#endregion}


Sign up for the ITPro Today newsletter
Stay on top of the IT universe with commentary, news analysis, how-to's, and tips delivered to your inbox daily.

You May Also Like