Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the reason for ICommand in Mvvm?

In application using a mvvm-approach it's pretty common that the ViewModel provides one or more Command-properties. These properties often have the type ICommand or DelegateCommand or something like that.

I don't understand why we need such an approach in an mvvm application. Wouldn't it be enough to provide public methods and bind the action from the view directly to this public method?

Why does ICommand exist?

like image 771
Ranga B. Avatar asked Feb 08 '17 12:02

Ranga B.


People also ask

What is ICommand used for?

Commands provide a mechanism for the view to update the model in the MVVM architecture. Commands provide a way to search the element tree for a command handler.

What is ICommand C#?

The ICommand interface is the code contract for commands that are written in . NET for Windows Runtime apps. These commands provide the commanding behavior for UI elements such as a Windows Runtime XAML Button and in particular an AppBarButton .

How do you implement ICommand in MVVM?

The idea - creating a universal command that takes two delegates: one is called when ICommand. Execute (object param) is invoked, the second checks the status of whether you can execute the command (ICommand. CanExecute (object param)) . Requires the method to switching event CanExecuteChanged .

What is ICommand interface implementation?

ICommand is an interface between the Presentation & the BusinessLogic layer. Whenever any button is pressed on the screen, XAML has its code-behind ButtonClick event. But in MVVM architecture, there is no room for code-behind to keep the application loosely coupled, so ICommand was introduced.


2 Answers

Wouldn't it be enough to provide public methods and bind the action from the view directly to this public method? Why ICommand exists?

  1. you can't bind to a method in xaml. You need an object. Therefore you need to wrap the method to an object.

  2. it is a common pattern in UI, that some actions are not available all the time. In Login form the Login action become available only when you enter username. In MS Word, the Copy or Cut actions becomes available only when you select something, otherwise the buttons are disabled and keyboard shortcuts inactive

  3. it is a common pattern, that command can be invoked with different parameters.

Plain eventhandlers does not meet those requirements, But ICommand servers exactly those purposes:

public interface ICommand
{
    void Execute(object parameter);
    bool CanExecute(object parameter);
    event EventHandler CanExecuteChanged;
}
  1. It wraps method to an object
  2. It says whether to command is available or no, so the UI component (typically a button or menuitem) can reflect it
  3. Additionally, it notifies the UI components that the availability of the command has changed, so the UI can reflect it.

Now, let's consider Copy&Paste scenario. Using ICommand the markup can look like this:

<Button Content="Paste" Command="{Binding PasteCommand}" />
<MenuItem Header="Paste" Command="{Binding PasteCommand}" />
public ICommand PasteCommand {get;} = new DelegateCommand(Paste, () => Clipboard != null);

How would it look like without ICommand? To make it easier, lets consider, that XAML would allow to bind to methods:

<Button Content="Paste" Click="{Binding Paste}" IsEnabled="{Binding CanPaste}" />
<MenuItem Header="Paste" Click="{Binding Paste}" IsEnabled="{Binding CanPaste}"/>

public void Paste() {....}

private bool _canPaste;
public bool CanPaste
{
    get { return _canPaste }
    set 
    { 
        if (_canPaste != value)
        {
            _canPaste = value;
            OnNotifyPropertyChanged(nameof(CanPaste);
        }
    }
}

as you can see, not only it is more verbose, but it's also violation of DRY principle. You need to specify both Paste and CanPaste binding every time you want to use the command. What if you started without CanPaste and later you wanted to add it. Then you would have to add the CanPaste binding every occurrence of the Paste call. I guarantee you, that you would forget it somewhere.

Now, if you did this in WPF:

<Button Content="Paste" Click="Call_ViewModel_Paste" />
//in codebehind:
void Call_ViewModel_Paste(oobject sender, RoutedEventArgs e)
{
    ViewModel.Paste();
}

or eventually:

<Button Content="Paste">
     <i:Interaction.Triggers>
         <i:EventTrigger EventName="Click">
             <ei:CallMethodAction MethodName="Paste" TargetObject="{Binding}"/>
         </i:EventTrigger>
     </i:Interaction.Triggers>
</Button>

Both approaches are correct, they follow MVVM priciples and works without ICommand, but as you can see, neither is as elegant as ICommand

like image 199
Liero Avatar answered Sep 19 '22 05:09

Liero


Wouldn't it be enough to provide public methods and bind the action from the view directly to this public method?

How would you for example call a public method when a Button in the view is clicked?

The answer is that you bind the Command property of the Button to an ICommand property of the view model that calls the method for you. That's the main reason why any actions that view model defines are exposed using commands.

A command is nothing but an object that implements the System.Windows.Input.ICommand interface and encapsulates the code for the action to be performed.

Please refer to the following links for more information about the concept.

https://blog.magnusmontin.net/2013/06/30/handling-events-in-an-mvvm-wpf-application/ https://msdn.microsoft.com/en-us/magazine/dn237302.aspx

like image 21
mm8 Avatar answered Sep 18 '22 05:09

mm8