Silverlight 4: Reliable Commanding with RequerySuggested Functionality?
One of the major problems I have been running into in Silverlight is its lack of robust Commanding support (ala WPF). More specifically, I find it very difficult to apply the MVVM pattern cleanly and with reasonable encapsulation because of the requirement to manually call RaiseCanExecuteChanged() on any property that can affect the state of a Command.
As an example, I have a parent/child View bound to a parent/child ViewModel. The parent View binds to a command on the parent ViewModel. The parent view has multiple child views, each of which is a userc开发者_开发技巧ontrol that contains a series of built-in controls (textboxes, comboboxes, etc.), which are bound to the child view model.
The state of the parent command (i.e. whether or not it can execute) is based on the state of each of the child controls. For example, all textboxes for all child usercontrols must have valid values. This requires the properties that these controls bind each call RaiseCanExecuteChanged(), which means they have to have knowledge of either the ICommand itself, or a delegate to call the RaiseCanExecuteChanged() method.
Injecting the command or delegate feels wrong to me, especially in situations more complex than described above, for example when there are 3+ layers of controls, and these references need to be passed all the way down the chain. It's also a bit more housekeeping, since each time a child gets instantiated, an extra step of adding the command or delegate has to be taken.
This would all be made much simpler if Silverlight supported CommandManager.RequerySuggested functionality, like WPF does.
I have seen articles that suggested it was possible to implement RequerySuggested in Silverlight (one such article), but see very little commentary on whether it's reliable and performs adequately.
How have others worked around this limitation with Silverlight?
One method I've used in the past is to use the messaging engine from Laurent Bugnion's MVVM Light framework (http://blog.galasoft.ch/archive/2009/09/27/mvvm-light-toolkit-messenger-v2-beta.aspx).
In essence, the children send a message to request that the commands be required. The listener, which can sit in the parent, responds to the messages and calls RaiseCanExecuteChanged().
I've found MVVM Light to be worth it just for the messaging engine. Though you do have to be careful and unregister the listener when the parent view is disposed.
Hope that helps.
精彩评论