Как создать RelayCommand с дополнительными параметрами

Я пытаюсь узнать об интерфейсе ICommand и немного запутался. Я хочу иметь команды, которые не требуют параметра object, потому что он никогда не используется.

class MainWindowViewModel
{
    private int ZoomLevel { get; set; }

    public bool CanExecute { get; set; }

    public ICommand ToggleExecuteCommand { get; set; }

    public ICommand IncrementZoomCommand { get; set; }

    public MainWindowViewModel()
    {
        IncrementZoomCommand = new RelayCommand(IncrementZoom, param => CanExecute);
        ToggleExecuteCommand = new RelayCommand(ChangeCanExecute);
    }

    public void IncrementZoom(object obj)
    {
        ZoomLevel++;
    }

    public void ChangeCanExecute(object obj)
    {
        CanExecute = !CanExecute;
    }
}

Вот мой класс RelayCommand

public class RelayCommand : ICommand
{
    private Action<object> execute;

    private Predicate<object> canExecute;

    private event EventHandler CanExecuteChangedInternal;

    public RelayCommand(Action<object> execute)
        : this(execute, DefaultCanExecute)
    {
    }

    public RelayCommand(Action<object> execute, Predicate<object> canExecute)
    {
        if (execute == null)
        {
            throw new ArgumentNullException("execute");
        }

        if (canExecute == null)
        {
            throw new ArgumentNullException("canExecute");
        }

        this.execute = execute;
        this.canExecute = canExecute;
    }

    public event EventHandler CanExecuteChanged
    {
        add
        {
            CommandManager.RequerySuggested += value;
            this.CanExecuteChangedInternal += value;
        }

        remove
        {
            CommandManager.RequerySuggested -= value;
            this.CanExecuteChangedInternal -= value;
        }
    }

    public bool CanExecute(object parameter)
    {
        return this.canExecute != null && this.canExecute(parameter);
    }

    public void Execute(object parameter)
    {
        this.execute(parameter);
    }

    public void OnCanExecuteChanged()
    {
        EventHandler handler = this.CanExecuteChangedInternal;
        if (handler != null)
        {
            handler.Invoke(this, EventArgs.Empty);
        }
    }

    public void Destroy()
    {
        this.canExecute = _ => false;
        this.execute = _ => { return; };
    }

    private static bool DefaultCanExecute(object parameter)
    {
        return true;
    }
}

Из-за того, что класс RelayCommand был реализован с использованием Action<Object> (кажется универсальным для SO), мне нужно передать объект в мой метод IncrementZoom. Мне кажется странным, что метод IncrementZoom должен передавать объект, который никогда не используется. Нужно ли мне создать еще один класс ParameterlessRelayCommand, в котором все подписи объектов удалены из конструкторов, методов, свойств и т.д....


person Ralt    schedule 07.07.2017    source источник
comment
Элементы UIElement с привязываемым свойством Command также имеют привязываемое свойство CommandParameter, значение которого передается в качестве аргумента объекта в Execute и CanExecute. Он может содержать простую строку или сложный объект, а также, конечно же, иметь значение null (что является значением по умолчанию, т. е. если вы не установили CommandParameter).   -  person Clemens    schedule 07.07.2017
comment
@Clemens Рад принять это как ответ, если вы хотите опубликовать. Я не знал, будет ли это выглядеть как нечистый код, и поскольку я не знал, почему это происходит, я не смог бы это оправдать.   -  person Ralt    schedule 07.07.2017