(X) Hide this
    • Login
    • Join
      • Generate New Image
        By clicking 'Register' you accept the terms of use .

Data Conversion in Silverlight Data Binding

(1 votes)
Emil Stoychev
>
Emil Stoychev
Joined Oct 15, 2007
Articles:   23
Comments:   98
More Articles
4 comments   /   posted on Jun 30, 2008
Categories:   Data Binding

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.

img01

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:

  1. 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>
  2. Set the converter using the Converter attribute
    <TextBlock Text="{Binding Birthdate, Converter={StaticResource BirthdateConverter}}"  />

The result looks like this:

img02

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:

img03

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


Subscribe

Comments

  • -_-

    RE: Data Conversion in Silverlight 2 Data Binding


    posted by Ali Daneshmandi on Oct 21, 2008 03:43

    Is there a way to bind The text value of textbox to itself. Don,t be confuesed. I have written a method which accept a string and then it returns that string in another format. Better say I want to do something like this:

    <UserControl.Resources>

    <myClasses:PersianFormattingConverter x:Key="PersianConverter"/>

     </UserControl.Resources>

    <TextBlock Text="{Binding txtOriginal.Tag, Converter={StaticResource PersianConverter}}" x:Name="txtPersian" Tag="گچ پژ پارسی"  TextAlignment="Right"/>

    In fact, I am wring an API to support Persian language in silverlight 2.0 because Silverlight doesnot support right to left text. So I have written a class to do that stuff. Now I can change the text of my controls in runtime in C# code to show persian text well. But I want to support it in design time, too.

    Thank you very much.


  • emil

    RE: Data Conversion in Silverlight 2 Data Binding


    posted by emil on Oct 21, 2008 06:56

    Hi Ali,

    I'm not aware of a way you can support that in design time. In my experience I would say that there is no way to do that, but don't just get my word for it.

    In WPF you can achieve that with

    <TextBlock Text="{Binding ElementName=txtOriginal, Path=Tag, Converter={StaticResource PersianConverter}}" x:Name="txtPersian" Tag="گچ پژ پارسی" TextAlignment="Right"/>

    Unfortunately the ElementName is not supported in Silverlight data binding. 


  • -_-

    RE: Data Conversion in Silverlight 2 Data Binding


    posted by Manoj on Dec 29, 2009 11:32
    Thanks a lot .This solved my problem
  • -_-

    RE: Data Conversion in Silverlight 2 Data Binding


    posted by CyberMan on Apr 25, 2010 17:56

    I'm binding a list to a datasource.

     Then running converters on the resultant values.

    However if I try to update the values from an event I seem to get the wrong values. Any clues? Is the databound converter returning the value before I update it from my event? Hence me getting an old verion of the value?

    Thanks if anyone has any clues on this.

Add Comment

Login to comment:
  *      *