Are there scenarios where the ViewModel needs to invoke methods on the View w.r.t. MVVM in WPF?
As per the pattern, the ViewModel exposes Properties(with change notification) and Comman开发者_开发问答ds (to notify the VM of user actions) that the View binds to. The only communication that flows from the VM to the View is the property change notifications (so that the View can refresh itself with updated data).
In MVP or PresentationModel form of the pattern (if I'm not mistaken), the View implements a plain vanilla interface (consisting of methods, properties and/or events). With MVVM, it feels methods on the IView have been outlawed (along with IView itself).
One scenario I could think of was to set the focus to a certain control in the View. (When the user does ActionX, the focus should immediately be set to FieldY).
- In MVP, I'd write this as IView.ActivateField(NameConstant), which the presenter or PM would invoke.
- In MVVM, this seems to be a fringe case that needs a workaround / little bit of code-behind. The VM implements an ActiveField Property, which it sets to NameConstant. The view picks up the change notification event and in a code-behind event handler, activates the Name control.
Is the above just an exception to the norm? Or are there other such scenarios, where the VM needs to invoke a method on the View ?
While it's discouraged for the ViewModel to call actual methods on the view, there are situations where being able to invoke a view action is beneficial. Most MVVM practitioners advocate a messaging system using the mediator pattern to handle VM to view communication, and if you look at the MVVM frameworks, such as MvvmFoundation, you can often see examples of such messenger systems at-work.
For myself, I have found the most common situations where I've needed to do this is with focus operations, as often setting the focus on the correct element with XAML can be a pain to setup, and being able to do something simple like...
Messenger.Notify("SetFocusOnElement");
can come in very handy.
Whenever you feel forced to use Code-behind, you perhaps can refactor it in a way that you create a general-purpose, reusable control or class that you can use declaratively in XAML. In your case, you could come up with your own FocusListener
class or the like, so that you can write:
<TextBox Text="{Binding SomeStuff}" myCtl:FocusListener.FocusWhen="{Binding SomeStuff}" />
It surely depends on your scenario if this approach can help you.
It's surely not a forbidden thing to extend the available classes and controls of WPF with some of your own.
Why shouldn’t you be allowed in the MVVM pattern to communicate with the View through an interface?
In MVP, I'd write this as IView.ActivateField(NameConstant), which the presenter or PM would invoke.
I wouldn’t start to implement a complicated workaround when the Interface approach is simple and doesn’t provide any drawbacks (e.g. testability).
More information can be found here: WPF Application Framework (WAF).
精彩评论