Question

In my project, i'd like to use MVVM (& Commands). I've started learning about commands and implementation of ICommand.

I'd like to create implementation of ICommand without parameters. (To trigger loading of data/flushing of data etc. - I don't need any parameters to do it, so it just seems natural to try and create command without parameters)

This is the code I'm using:

using System.Windows.Input;

public class NoParameterCommand : ICommand
{
    private Action executeDelegate = null;
    private Func<bool> canExecuteDelegate = null;
    public event EventHandler CanExecuteChanged = null;

    public NoParameterCommand(Action execute)
    {
        executeDelegate = execute;
        canExecuteDelegate = () => { return true; };
    }
    public NoParameterCommand(Action execute, Func<bool> canExecute)
    {
        executeDelegate = execute;
        canExecuteDelegate = canExecute;
    }

    public bool CanExecute()
    {
        return canExecuteDelegate();
    }
    public void Execute()
    {
        if (executeDelegate != null)
        {
            executeDelegate();
        }
    }
}

But i got errors about not implementing the ICommand interface in the right manner ('XXX.YYYY.NoParameterCommand' does not implement interface member 'System.Windows.Input.ICommand.Execute(object)')

So I thought about doing it like this instead:

(Added the parameters that were missing from CanExecute and Execute)

public class NoParameterCommand : ICommand
{
    ...omitted - no changes here...

    public bool CanExecute(object parameter) //here I added parameter
    {
        return canExecuteDelegate();
    }
    public void Execute(object parameter)    //and here
    {
        if (executeDelegate != null)
        {
            executeDelegate();
        }
    }
}
  1. IS THIS A GOOD WAY TO DO IT?
  2. SHOULD I USE ANOTHER WAY? (IF SO, WHAT SHOULD I DO INSTEAD?)
Was it helpful?

Solution

  1. This is a good way to do it.
  2. No, you should not use another way.

Additional suggestions:

Thinking about this again, I would improve your architecture by introducing an additional hierarchy level where CanExecute() and Execute() are abstract. From that class, derive your command class that invokes delegates.

This way, you can decide later on whether you want to supply your logic for your parameterless commands via delegates or via subclassing your base command class.

OTHER TIPS

I'm not really sure what your concern is. It is common to ignore the parameters in the ICommand interface.

If you really want CanExecute and Execute methods that don't have parameters, you can implement the interface explicitly (rather than implicitly). The ICommand methods will still exist, but to anyone looking at your object from the outside, they won't be able to see those methods:

bool ICommand.CanExecute(object parameter) { this.CanExecute(); }

public bool CanExecute()
{
  //do work
}

You are essentially hiding the interface implemenation. If someone wants to directly call the CanExecute method from the interface, they would have to type cast to ICommand in order to do it. You really don't gain anything in doing it this way, but if you are concerned with how your class looks to outside developers (e.g. you are developing an API), then this can make it look a little cleaner as you are letting them know you do not require any parameters.

I personally prefer it this way:

public class MyCommand : ICommand
{
    private static bool True() { return true; }

    private readonly Action _execute;
    private Func<bool> _canExecute;
    private Func<bool> _isVisible;

    public event EventHandler IsVisibleChanged;
    public event EventHandler CanExecuteChanged;

    public MyCommand(Action execute, Func<bool> canExecute = null, Func<bool> isVisible = null)
    {
        _execute = execute;
        _canExecute = canExecute ?? True;
        _isVisible = isVisible ?? True;
    }

    public void Execute()
    {
        _execute();
    }

    public Func<bool> CanExecute
    {
        set
        {
            _canExecute = value ?? True;
            CanExecuteChanged(this, new EventArgs());
        }
        get { return _canExecute; }
    }

    public Func<bool> IsVisible
    {
        set
        {
            _isVisible = value ?? True;
            IsVisibleChanged(this, new EventArgs());
        }
        get { return _isVisible; }
    }

    bool ICommand.CanExecute(object parameter)
    {
        return CanExecute();
    }

    void ICommand.Execute(object parameter)
    {
        Execute();
    }
}

However, since the delegates usually don't change, I prefer an immutable version:

[ImmutableObject(true)]
public class MyImmutableCommand : ICommand
{
    private static bool True() { return true; }

    private readonly Action _execute;
    private readonly Func<bool> _canExecute;
    private readonly Func<bool> _isVisible;

    [Obsolete("Will not be invoked, because the implementation never changes.")]
    public event EventHandler CanExecuteChanged;

    public MyImmutableCommand(Action execute, Func<bool> canExecute = null, Func<bool> isVisible = null)
    {
        _execute = execute;
        _canExecute = canExecute ?? True;
        _isVisible = isVisible ?? True;
    }

    public bool CanExecute()
    {
        return _canExecute(); 
    }

    public bool IsVisible()
    {
        return _isVisible(); 
    }

    public void Execute()
    {
        _execute();
    }

    bool ICommand.CanExecute(object parameter)
    {
        return CanExecute();
    }

    void ICommand.Execute(object parameter)
    {
        Execute();
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top