如何使用可选参数创建RelayCommand

时间:2017-07-07 07:55:09

标签: c# wpf data-binding icommand 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,该类具有从构造函数,方法,属性等中删除的所有对象签名...

0 个答案:

没有答案