First let us answer in short: - “Delegate command makes a MVVM command class independent of the view model”. Now let’s understand the long way.
In MVVM architecture view talks with the view model and view model talks with the model. When actions are sent from the view they are sent to WPF commands for handling the events. WPF commands invoked methods of view model internally.
In other words command needs reference of view model class.
If you see a typical WPF MVVM command it looks as shown below. You can see the “CustomerViewModel” class referenced inside the ‘btnCommand” class. If you think with your eyes closed this reference of “CustomerViewModel” class inside the command is a problem. This will lead to tight coupling between command classes and view model.
If you visualize command it is nothing but click , double click , left mouse click , drag and drop etc. It’s an ACTION created by the user. Now wouldn’t be great if we can just attach this command with any view model. So like click event gets connected with “CustomerViewModel” or “SupplierViewModel”.
This is achieved by using delegate command.
public class btnCommand : ICommand
{
Private CustomerViewModel Viewobj = new CustomerViewModel();
public btnCommand(CustomerViewModel obj)
{
Viewobj = obj;
}
public bool CanExecute(object parameter) // When he should execute
{
return Viewobj.IsValid();
}
public void Execute(object parameter) // What to execute
{
ViewObj.Add();
}
}
To decouple the view model class from command we can use delegates i.e. “Action” and “Func”. If you see the command class we need only two things “WhattoExecute” and “WhentoExecute”. So how about passing these methods as generic delegates. You can see the constructor of “btnCommand” takes two delegates one what to execute and when to execute.
You can see in the below code the “btnCommand” class has no reference of the view model class but has references to delegates which are just abstract pointer to functions / methods. So this command class can now be attached with any view model class. This approach is termed as “Delegate command”.
public class btnCommand : ICommand // Step 1 :- Create command
{
private Action WhattoExecute;
private Func<bool> WhentoExecute;
public btnCommand(Action What , Func<bool> When)
{
WhattoExecute = What;
WhentoExecute = When;
}
public bool CanExecute(object parameter) // When he should execute
{
return WhentoExecute();
}
public void Execute(object parameter) // What to execute
{
WhattoExecute();
}
}