views:

677

answers:

2

I am using WPF and the MVVM pattern in my user interface. In my ViewModel I have a List containing distances in millimetres, which I display in a ListView by binding ListView.ItemsSource to the List. However, I would like the values displayed to use a more natural unit - either metres or feet depending on the state of a "metric" checkbox.

I have written a couple of simple classes, MillimetresToMetresConverter and MillimetresToFeetConverter, both of which implement IValueConverter. Although I can set the Converter property on my data binding to one or the other, I am unsure how to change between these converters when the state of the checkbox changes.

My plan was to have a field "IValueConverter lengthConverter" on my ViewModel which I could set to one converter or the other, then in my XAML do ...="{Binding Converter={Binding Path=lengthConverter}}" - unfortunately this does not work since Converter is not a dependency property.

How can change the converter used by the data binding at runtime?

A: 

If I may suggest a simple alternative solution: Create a small FormatMillimetresConverter in your ViewModel, whose UseMetric property is bound to the "metric" checkbox.

Heinzi
Thanks - but once I've got a FormatMillimetresConverter in the ViewModel, how do I get the ListView to use it?
Paul Baker
Good point. :-) You could export one instance of it as a static property of your ViewModel and then access it via "... Converter={x:Static local:ViewModel.MyFormatMillimetresConverter}", but somehow that's not very elegant...
Heinzi
What about creating the FormatMillimetresConverter in <Window.Resources>? Then it's available as a static resource and you can attach it as a converter to the ListView.ItemsSource with "... Converter={StaticResource..." and to the checkbox with "{Binding Source={StaticResource...".
Heinzi
+3  A: 

Most of the time when using the MVVM methodology, you can do the formatting task in the VM classes. In your case, you could add a Format property to the VM class, and based on the value of the Format property, return a well formated string.

See this discussion for more information.

Jalfp
Exactly. Converters are very rare in an MVVM application, normally only popping up in custom controls.
Kent Boogaart
Let's assume my ViewModel has a `List<int> Distances` property which I am binding my ListView.ItemsSource to. Are you suggesting that instead of Distances.get returning the list as-is, it should return a different list - with the conversion already applied?
Paul Baker
@Paul: yep. A ViewModel is just a bit ValueConverter ;-). You can read a similar discussion on the WPF Disciples discussion board: http://groups.google.com/group/wpf-disciples/msg/c29b3935ec9d3c4e
Anderson Imes
Maybe I oversimplified when asking the question. Let's assume that instead of List<int>, I have List<LargeDataStructure> and I want to apply a conversion to a single member of LargeDataStructure. It seems to be quite heavy-handed to create and expose List<NewLargeDataStructure>, where a NewLargeDataStructure references a LargeDataStructure (or worse, makes a copy of it) and re-exposes all but one of its properties in the same way. A ValueConverter seems much lighter - just changing the single property "on the fly".
Paul Baker