Original: WPF MVVM architecture Step by Step (6) (Decoupling actions from view model)
So far, we've created an example of a simple MVVM that contains the implemented properties and commands. We now have a view that contains an INPUT element such as a TextBox, and the TextBox uses a binding to contact the view model, such as clicking the button to contact the behavior with a command. The view model and model communicate internally.
But there is a problem in the schema above, and the command class and the view model have a very serious coupling. If you remember the Command class code (shown below), passing the view model object in the constructor means that the command class cannot be reused in any other view model.
Public class buttoncommand:icommand{ private customerviewmodel _obj; Public Buttoncommand (Customerviewmodel obj) { = obj; } ............}
But now we're thinking about what a behavior is. It is a kind of event from end user like mouse click, button click, menu click, press function key etc. So there should be a way to summarize these behaviors and attach them to the view model in a more generic way.
If you think that logical behavior is the logic contained in methods and functions, what is a common way to point to methods and functions? Think about it, that's the Commission.
We need 2 delegates, one for CanExecute and another for execute. CanExecute returns a Boolean value, which is used to validate and then allow and disallow user interfaces based on validation. Execute when CanExecute is true.
Public class Buttoncommand:icommand { publicbool canexecute (object parameter) { // Validation Code } publicvoid Execute (object parameter) { // Execute logic } }
In other words, we need 2 delegates, 1 functions that return a Boolean value, and another action returns NULL. So just so we can create a Func and an action. By means of a delegate, we try to create a generic class. In the command class we made the following 3 changes:
- We remove the view model object from the constructor, the input becomes 2 delegates, and one is the Func one is the action. Func is used to verify that action is used to execute. The values of the 2 delegates are passed through the constructor to the private variables passed to the class.
- Func delegate = CanExecute
- Action delegate = what to Execute
Public classButtoncommand:icommand {PrivateAction _whattoexecute; Privatefunc<BOOL>_whentoexecute; PublicButtoncommand (Action what,func<BOOL>When ) {_whattoexecute=what ; _whentoexecute=When ; } Public BOOLCanExecute (Objectparameter) { return_whentoexecute (); } Public voidExecute (Objectparameter) {_whattoexecute (); } Public EventEventHandler canexecutechanged; }
In model, we already know what to Execute-calculatetax, and we used a simple function (IsValid) to verify that the customer class is available.
Public classCustomer { Public voidCalculatetax () {if(Amount > -) {_tax= -; } Else if(Amount > +) {_tax=Ten; } Else{_tax=5; } } Public BOOLIsValid () {returnAmount! =0; } }
In the View model class, we pass 2 parameters, a Func, an action.
public class customerviewmodel:inotifypropertychanged{ Private readonly Buttoncommand _ Objbuttoncommandcommand; public Customerviewmodel () {_ Objbuttoncommandcommand =new Buttoncommand (obj. Calculatetax,obj. IsValid); public ICommand calclick => _objbutt Oncommandcommand; private Customer obj = new Customer ();}
This makes the architecture even better and because the command class can be decoupled using a common approach and any view model. Here is the improved architecture, and notice how the view model communicates with the command class through delegates.
Prism is a good framework in an MVVM architecture. The main use of PRISM is for modular development, which has a nice delegatecommand class that is much better than creating our own command class ourselves.
prism:http://www.microsoft.com/en-in/download/details.aspx?id=42537
WPF MVVM Step by Step Original: Http://www.codeproject.com/Articles/819294/WPF-MVVM-step-by-step-Basics-to-Advance-Level
WPF MVVM Architecture Step by Step (6) (Decoupling actions from view model)