A recent post by Josh Twist shows how to support mingling code in XAML for WPF devs. There have been several examples of putting code into XAML over the years, and they always raise the discussion of whether or not it is a good practice. I am usually against having code in XAML because it makes it difficult to debug and maintain, but to each his/her own. Regardless, that post got me thinking…
For a while now I’ve wondered how one might go about making it so that the little bits of code in the XAML might somehow be transplanted into the highly testable, debuggable, lovable world of the ViewModel. Sure, you could put this type of logic into value converters, but writing a value converter that is only used once seems like a lot of extra work for little benefit.
Just for kicks, I decided to implement a class that would allow you to specify a method on your ViewModel object that contains the code that would otherwise be placed into a value converter, or in XAML. The result is a markup extension I ever so lazily named BindingEx. Here’s a simple usage:
Notice the last bit where the ConvertMethod property is set to AdjustTextWidth. This is how you specify which method on the element’s VM should be invoked when the window’s width changes. Here’s the VM class:
The TextViewModel object halves the window’s ActualWidth, and that value ends up being the width of the TextBlock.
I’m not sure that anyone should ever use this technique in a real application. It’s probably a very stupid idea altogether, so I want to avoid any bad karma by stressing the point here: USE AT YOUR OWN RISK!!
If you want to check out how I implemented BindingEx, click here to download the source code. Be sure to change the file extension from .DOC to .ZIP and then decompress it.
I kind of like your idea too. Although, if you think about it, you may use an expression containing a method in Josh T’s implementation (if it supports it) to achieve the same result.
I would at least go for a converter that accepts a type rather than a resource. Having to write a resource named as a type the contains just the type of a converter in the XAML really annoys me. Why not use something like Converter={x:Type MyConverter} or Converter={x:Method MyMethod} ?
[…] Using a ViewModel as a value converter (Josh Smith) […]
Hi, I’ve got a similar thing for ICommand binding to ViewModel’s methods. You would likely want to check it out, there’re couple of tricks there for simpler XAML syntax, multi-binding. MethodCallThing.codeplex.com
@Siderite – I wanted to avoid having code in XAML altogether. Also, the Converter={x:Method MyMethod} won’t work because the MarkupExtension.ProvideValue method’s ‘serviceProvider’ argument wouldn’t have references to the bound element, which is necessary to get at its DataContext.
@Oleg – Thanks for pointing out your MethodCallThing.
Hey Josh,
It’s not a bad idea but I want to rather try and integrate a lambda converter in MVVM Light Toolkit. Probably won’t make it in this version though. The lambda converter takes a lambda expression as a string, and invokes it dynamically. Marlon wrote about that some time ago, as well her this person: http://www.fikrimvar.net/lestirelim/?p=15
Cheers,
Laurent
However, in this case one wonders why would ViewModel expose both pre-calculation value and calculation logic.
If XAML/View is only interested in post-calculation, ViewModel should simply expose post-calculation and hide all the meaty specifics.
If the actual calculation does belong to the View, it’s only natural to put it into XAML. Although it’s obvious XAML is not an expression-friendly thing. The ultimate solution seems still to be somewhere around the corner.
[…] Using a ViewModel as a value converter […]