Reply to comment
Replace INotifyPropertyChanged
Update (March 2, 2011)
The information in the original post is no longer accurate. Now when Update Controls finds an object that implements INotifyPropertyChanged, it will step out of the way. The assumption is that if you implement this interface, you intend to manage your own dependencies.
If an object that implements INPC has a child object that does not, the child object is not wrapped either. Once you implement INPC, you are responsible for all of its children. If you want Update Controls to wrap a child object, you must call ForView.Wrap() inside the property getter. This is not recommended, since a view model that implements INPC should have no dependency upon Update Controls.
The original post is preserved for historical continuity.
Original post (October 10, 2009)
I recently corresponded with a new Update Controls user. He brought up some excellent points about INotifyPropertyChanged and Update Controls. The short answer is: don't mix them. Unfortunately, reality is not so cut and dried.
We started with some easy questions:
Should my view model implement INotifyPropertyChanged [when I'm using Update Controls]?
No, your view model should not implement INotifyPropertyChanged. When you call ForView.Wrap(), Update Controls implements it for you.
So ForView.Wrap() completely replaces the "{u:Update}" syntax?
Absolutely, it does. It is more Blend friendly.
But do I still need to define my Independent's using Ctrl+D, G?
Yes, the underlying dependency tracking is still exactly the same. It still requires Independent sentries, which Ctrl+D, G generates for you.
And then the hard questions began:
If I exposed properties of an object that implements INotifyPropertyChanged (for example, CslaDataProvider.IsBusy) via my ViewModel, do I need to do anything special? Or would it be so simple as:
public bool IsBusy { get { return _dp.IsBusy; } }
Unfortunately, ForView.Wrap() hides the INotifyPropertyChanged implementation of the root object or any of its properties. So simply passing through the property access would not be sufficient. Neither does the dependency tracking mechanism recognize INotifyPropertyChanged. So when the event is fired, Update Controls does not know to forward that along to the view.
If your class already implements INotifyPropertyChanged and you want to add Independent sentries too, that's fine.
public class Customer : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private string _name; private Independent _indName = new Independent(); public string Name { get { _indName.OnGet(); return _name; } set { _indName.OnSet(); _name = value; FirePropertyChanged("Name"); } } private void FirePropertyChanged(string name) { if (PropertyChanged != null) PropertyChanged.Invoke(this, new PropertyChangedEventArgs(name)); } }
The INotifyPropertyChanged implementation will be completely ignored by Update Controls, and the Independent will be completely ignored by legacy code.
Or, if you have a legacy object and you completely control the access to its properties, you can wrap it.
public class CustomerWrapper { private Customer _customer; private Independent _indCustomerName = new Independent(); public CustomerWrapper(Customer customer) { _customer = customer; } public string Name { get { _indCustomerName.OnGet(); return _customer.Name; } set { _indCustomerName.OnSet(); _customer.Name = value; } } }
But if someone else could change the controlled property without going through your code, you have to handle INotifyPropertyChanged yourself.
public class CustomerWrapper { private Customer _customer; private Independent _indCustomerName = new Independent(); public CustomerWrapper(Customer customer) { _customer = customer; _customer.PropertyChanged += (sender, e) => { if (e.PropertyName == "Name") _indCustomerName.OnSet(); }; } public string Name { get { _indCustomerName.OnGet(); return _customer.Name; } set { /*_indCustomerName.OnSet(); Not needed anymore. */ _customer.Name = value; } } }
When the event fires, you record that the property has been set. I'd love to generate a wrapper for you (something like ForViewModel.Wrap()), but I can't think of a way of doing that without hiding the underlying object properties. Maybe with some Ayende mojo I could pull it off, but I'm hoping that I never have to.

Recent comments
2 weeks 2 days ago
8 weeks 4 days ago
8 weeks 4 days ago
8 weeks 5 days ago
8 weeks 6 days ago
11 weeks 4 days ago
11 weeks 5 days ago
12 weeks 4 days ago
12 weeks 5 days ago
13 weeks 18 hours ago