This article is compatible with the latest version of Silverlight.
A common scenario in data binding is to format the data displayed in the UI. Almost every time you show a date or a price you need to format it. Silverlight and WPF are using the so called converters to apply custom logic to a binding.
Using Converters
Let's make a small example that illustrates the problem. Consider a ListBox filled with client details - name and birthdate.
Here the ListBox is bound to a custom business object with a field Birthdate of type DateTime - pretty common situation. In most cases what you need to be displayed for a date of birth is only the year, the month and the day. So the time (12:00:00 AM) is redundant. To set a custom format for the birth date we need to create a custom converter by implementing the IValueConverter interface.
public class BirthdateConverter : IValueConverter
{
public object Convert( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture )
{
DateTime dt = (DateTime)value;
return dt.ToString( "dd MMM, yyyy", culture );
}
public object ConvertBack( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture )
{
throw new NotImplementedException();
}
}
The IValueConverter interface has two methods that should be implemented - Convert and ConvertBack. The Convert method is used to convert the passed value. The ConvertBack method is used in two-way databinding scenarios to convert the input value back to the source type.
To apply the converter we need two steps:
- Add the converter in the resource collection of your control
<UserControl x:Class="UsingTypeConverters.Page"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:UsingTypeConverters"
Width="400" Height="300">
<UserControl.Resources>
<local:BirthdateConverter x:Key="BirthdateConverter" />
</UserControl.Resources>
...
</UserControl>
- Set the converter using the Converter attribute
<TextBlock Text="{Binding Birthdate, Converter={StaticResource BirthdateConverter}}" />
The result looks like this:
That looks nicer.
Let's tweak it a little bit more. In Silvester (the Twitter client I wrote about) the tweet structure contains a username that links to the user's profile in Twitter. The username is actually a HyperlinkButton control with a NavigateUri attribute set. NavigateUri attribute expects a value of type Uri to be passed. However the Uri type can't be serialized (because it doesn't have a parameterless constructor) and instead of Uri a string type is passed. To work properly this string should be converted before passed to the NavigateUri attribute. Let's take our example and make the name to link to a profile page.
<TextBlock Text="Name" FontWeight="Bold"></TextBlock>
<HyperlinkButton Content="{Binding Name}" NavigateUri="{Binding ProfilePage, Converter={StaticResource ProfilePageUriConverter}}" />
<TextBlock Text="Birthdate" FontWeight="Bold"></TextBlock>
<TextBlock Text="{Binding Birthdate, Converter={StaticResource BirthdateConverter}}"></TextBlock>
The ProfilePageUriConverter is added in the user control's resource just as the BirthdateConverter. This time we need to convert from string to Uri.
public class UriConverter : IValueConverter
{
public object Convert( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture )
{
string uriString = ( string )value;
Uri outputUri = null;
if ( !Uri.TryCreate( uriString, UriKind.RelativeOrAbsolute, out outputUri ) )
{
// handle exception
}
return outputUri;
}
public object ConvertBack( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture )
{
throw new NotImplementedException();
}
}
The final result is:
Summary
With the help of converters we can easily convert from one type to another and format data the way we want. Formatting data is an every day task so keep the converters in mind when building WPF and Silverlight applications.
References
DataBinding Overview on MSDN
IValueConverterInterface on MSDN
Working with Data - Silverlight QuickStarts
Silvester - A Silverlight Twitter Widget by Emil Stoychev