This time I’m complaining about an obvious glitch that kept throwing me off for some hours. Before I talk about it, I must state that I really love MVVM as a pattern, because it is such a ginormous improvement above the classic MVC-pattern, which I honestly hated instantly when I began developing. Sure I used it, but I never liked it.
So far with history, let’s start with the main article.
Assume you got a ViewModel that you have bound to the DataContext of your control, one property that is used for DataBinding looks like this:
We got a text control in our application, plus a ribbon instead of a classic menu bar. The ribbon’s “Bold” toggle button (like in MS Word) has its “IsChecked” property bound to the above property. Whenever the user clicks the button, the currently selected text will be bolded, and unbolded if he clicks again. Also, the button’s state will now change its state according to the format the text got at the current’s cursor location (done with the INotifyPropertyChanged‘s only method that forces WPF to update the bound properties).
So far, so standard and working.
But, imaginge if the above property had no setter (just a getter), and the binding looked like this (pay attention to the highlighted portion):
Please remember to remove the setter from your above property (as described above). Then run the application, wait for an “OnPropertyChanged()” method to be called for that property, and visit how it sometimes won’t work at all – the button will stay as it was or it will behave unpredictably. Please also note that this behavior might often appear, but sometimes don’t. I and my workmate can confirm this behavior.
The workaround is simple: Remove the “Mode=OneWay” statement and put an empty setter into the desired property. And voila – it will work as intended.
I think this is a problem that is unnecessary to be in WPF, since solving this problem took me at least one hour.
I can’t think of a better explanation than this: Whenever you use “Mode=OneWay“, the mode isn’t really One-Way unless you got at least the Get and Set-Methods in your property. If you haven’t got the Set-Method, then the One-Way won’t work. Why is that? Actually I don’t know. I haven’t disassembled the WPF-Framework’s source, and I won’t do it just for that, but I think it is an error afterall and worth noting.
It’s interesting – right now I’ve set up a mock test project with just a viewmodel, a button, a checkbox, and a property called “chkChecked”.
The button updates the ViewModel’s “chkChecked” property which in turn will raise the OnPropertyChanged() method which eventually updates the checkbox. And guess what – it worked! That’s somehow random, because – as I’ve told earlier in this article – it didn’t work the same way with the ribbon! Something mystic is going on here… but for now, I know how to circumvent rare cases when MVVM seems to throw you off ;)
Have a nice day!