Comments are closed for this post.
10 Mar 2009
Why do we need to suppress onChanged action in constructor?
I see no way BindingOperations.SetBinding could mess with delegate assigment. When we are in ValueChangedCallback doesn't that mean that binding is already successfull? Why bother with suppression?
10 Mar 2009
This looks like a great start!
I've been having similar thoughts as we think about how view models compose, propagate change notifications etc.
12 Mar 2009
I found that the binding was firing as I hooked it up so decided to suppress as I didn't feel this would be the expected behavior for my class.
Thanks - I look forward to seeing it in System.ComponentModel ;)
13 Mar 2009
This looks great! We've been doing quite a bit of thinking on what we can do to simply the whole binding / notification experience, and make the code cleaer.
I like the binding object abstraction and the delegate based approach for the change notification, as an additional benefit is that it gives greater testability.
The latch mechanism for suppressing change notification is also very nice.
The one downside i see from the weakly type string prop name is that the compiler can't help you / you can't leverage refactoring tools. Have you thought of making it an expression?
Can you share a sample view model so we can see how you are using it within?
16 Mar 2009
This is really cool!
14 Apr 2009
Did you consider using Mediator Pattern? I was going thru josh smiths blog http://joshsmithonwpf.wordpress.com/
where he mentioned this. Since I use Composite application guidance, we tackle this using Eventaggregator.
In one of the places when i encountered the same problem and did not want to over use eventaggregator, we resolved this by having multiple views talking to the same presentation model and Strategy pattern ! Also, ur blog is awesome! :)
15 Apr 2009
I too use Prism and the EventAggregator however, I'd prefer to bind to the ViewModel in the way I describe above because there's less friction - I don't have to change the ViewModel.
Also, and perhaps most importantly, if I bind to a property like so:
new BindingObject(sourceObject, "SomeObject.SomeProperty.SomeValue", e => Changed(e));
Then even if SomeObject's SomeProperty is changed, I'll be bound to the SomeValue of the new SomeProperty object. This scenario is *much* more complicated to do it with back-references/brokers/mediators. It's a doddle with WPF's binding engine though.
PS - thanks for the compliment :)
07 Jul 2009
This is a neat way to work around the fact that your ViewModels are not DependencyObjects, but now your ViewModels are relying on DependencyObjects.
This is unfortunate, in my mind, because DependencyObjects are view objects being referenced by the ViewModel. I could ignore this if it were for purity alone. Unfortunately, I the problem I run into happens during testing with Silverlight.
When we are using NUnit to test your ViewModel in Silverlight, we get an exception as soon as we instantiate the BindingObject. This is because the base constructor for DependencyObject relies on the Silverlight runtime being instantiated... in a unit test, this is not the case.
That being said, I have also struggled with this myself. It turns out that the problem of binding is not terribly difficult. I just wrote my own binder. It works directly against any object that implements INotifyPropertyChanged. If both objects implement INotifyPropertyChanged, you get 2-way binding. I also can attach events to specific properties changing.
That approach works well, but it is a shame we have to re-invent the wheel. Ideally, WPF and Silverlight binding would not rely on DependencyProperties and therefore DependencyObjects. It is a shame that they don't. DependencyProperties are ugly as sin, in my humble opinion.
That being said, I have grown to prefer the EventAggregator in Prism for intra-ViewModel communication. Mostly because eventing tends to be a more proper analogy to what is happening between the VMs than binding, in my experience.
All in all, I love seeing clever ways of getting around binding limitations. It at least reduces your requirement that your ViewModel be a DependencyObject, which I really appreciate.