Feed Icon  

Contact

  • Bryant Likes
  • Send mail to the author(s) E-mail
  • twitter
  • View Bryant Likes's profile on LinkedIn
  • del.icio.us
Get Microsoft Silverlight
by clicking "Install Microsoft Silverlight" you accept the
Silverlight license agreement

Hosting By

Hot Topics

Tags

Open Source Projects

Archives

Ads

Silverlight IValueConverter vs. TypeConverter

Posted in Silverlight at Sunday, 23 November 2008 22:40 Pacific Standard Time

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:
Tuesday, 25 November 2008 02:22:08 (Pacific Standard Time, UTC-08:00)
"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).
Odegaard
Tuesday, 25 November 2008 04:36:51 (Pacific Standard Time, UTC-08:00)
I agree it isn't as simple as how WPF does it, but WPF also requires Windows and a hefty download and install process. :)
Bryant Likes
Saturday, 23 May 2009 15:08:41 (Pacific Daylight Time, UTC-07:00)
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.
Nathan
Friday, 05 June 2009 03:43:47 (Pacific Daylight Time, UTC-07:00)
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
Karine
Friday, 05 June 2009 22:05:58 (Pacific Daylight Time, UTC-07:00)
I solved my problem. Thanks for the great post!
Karine
Karine
Comments are closed.