Bryant Likes's Blog

It's all about WebData

Recent Posts

Tags

News


  • Windows Live Alerts
    View Bryant Likes's profile on LinkedIn

    Me

    Get Microsoft Silverlight
    by clicking "Install Microsoft Silverlight" you accept the
    Silverlight license agreement


    The posts on this weblog are provided "as is" with no warranties and confer no rights. The opinions expressed herin are the personal opinions of the individual authors and do not represent the views of Avanade in any way.

Community

Email Notifications

Archives

Silverlight IValueConverter vs. TypeConverter

This is something that wasn’t clear to me so I decided to blog about so that I could fully understand it. Both IValueConverters and TypeConverters are used to do conversions (imagine that!), but they are used differently.

TypeConverters are used by the Xaml parser during parse time to convert values in the Xaml into values in CLR objects. So when you set Height=”100”, height isn’t a string so it has to be converted to a double. This is done using a type converter. Type converters are also one-way since once the value has been converted from Xaml to CLR it doesn’t have to go back. Custom type converters must be placed on the class they will be used on in order for them to work since otherwise the Xaml parser doesn’t know how to convert the value. There is a good MSDN article on TypeConverters which offers much more information.

IValueConverters are used during data binding via a property path. Typically these get created as a static resource in your Xaml file and then are referenced in the binding. Unlike type converters, value converters can go both ways since bindings can be two way bindings. Since value converters are specified in the binding they are much more dynamic and don’t require any references such as the type converters do. Value converters are also more flexible in that they can be passed a parameter via the ConverterParameter. You can read this great blog post on how this works if you’re interested.

A good example of how value converters make Silverlight more extensible is this question in the Silverlight forums. Odegaard was binding to a Dictionary object and was trying to get one of the keys to show up in his TextBlock.Text property. However, even though WPF supports this property bag type of binding, there is no way to do this directly in Silverlight. To get this type of binding to work you can use an IValueConverter. In this case the value converter would get the key in the dictionary and return the proper value. You can see the code for this in the original post (although the questioner didn’t like my implementation because it was too complicated, I thought it was rather simple).

I tried to come up with a more generic approach instead of requiring the dictionary to be of type Dictionary<string,string>, however the best I was able to do was have the value type be assignable but the key still had to be a string.

public class DictionaryItemConverter : IValueConverter

{

    public string ValueType { get; set; }

 

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)

    {

        Type generic = typeof(Dictionary<,>);

        Type[] typeArgs = new Type[] { typeof(string), Type.GetType(ValueType) };

        Type dictType = generic.MakeGenericType(typeArgs);

 

        if (dictType.IsInstanceOfType(value))

        {

            return dictType.GetMethod("get_Item").Invoke(value, new object[] { parameter });

        }

        throw new InvalidCastException(string.Format("Dictionary is not of type Dictionary<stirng,{0}>.", ValueType));

    }

 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)

    {

        throw new NotImplementedException();

    }

}

So hopefully this post has been helpful for you in understanding IValueConverters vs. TypeConverters and when to use them. It has cleared it up for me. :)

Technorati Tags:
Posted: 11-24-2008 6:40 AM by bryantlikes | with 6 comment(s)
Filed under: ,

Comments

Odegaard said:

"although the questioner didn’t like my implementation because it was too complicated, I thought it was rather simple"

Simple? No! This is simple and how WPF does it (NO code required what so ever):

<TextBlock Text="{Binding Path=.[ID], Mode=OneWay}" />

It's not that I don't understand it (I've used IValueConverters numerous times already). The problem I have with it, is that it's tedious work, and you end up having all these specialized converters, and XAML and code is suddenly much tighter linked together. The other problem is conveying this to other people using my code who might not think this is simple. Compared to all the other binding options you have, this is just way too complex for many people.

Btw, TypeConverters isn't really that new. It's been around in ASP.NET for quite some time now, and its exactly the same thing in XAML/Silverlight (at Beta2 they did have a different signature though, but is now in line with .NET's TypeConverter).

# November 25, 2008 10:22 AM

bryantlikes said:

I agree it isn't as simple as how WPF does it, but WPF also requires Windows and a hefty download and install process. :)

# November 25, 2008 12:36 PM

Community Blogs said:

In this issue: Timmy Kokke, Martin Mihaylov(2), CASON Engineering Plc., Bryant Likes(2), and Stefan Olson

# November 28, 2008 10:20 AM

Nathan said:

Just a minor detail concerning TypeConverters. TypeConverters are two way, they are often used by control designers to persist CLR control data to (Xaml,HTML,Xml,Code-Gen etc...). I have written two way TypeConverters for custom Asp.Net Web Controls as well as Windows Forms Controls. To my knowledge there is no designer support for SilverLight just yet but I think it is on the way.

# May 23, 2009 10:08 PM

Karine said:

Hi Brian,

You DictionaryItemConverter is right what I'm looking for. I try to parse XML rows (where the attributes are the properties) into a dictionary. Now I want to apply data binding.

In the usercontrol resources I put:

<sp:DictionaryItemConverter x:Key="spConverter" />

(the namespace is declared in the UserControl element)

An the binding as follows:

<TextBlock Text="{Binding Path=Title, Converter=StaticResource spConverter, Mode=OneWay}"

Margin="5" Style="{StaticResource TitleBlock}" FontWeight="Bold" />

Is this correct? Or do you have another XAML sample that you can provide me?

Thanks in advance!

Karine

# June 5, 2009 10:43 AM

Karine said:

I solved my problem. Thanks for the great post!

Karine

# June 6, 2009 5:05 AM
Leave a Comment

(required) 

(required) 

(optional)

(required)