ICommand总是需要一个对象作为参数吗?

时间:2013-03-08 09:10:35

标签: mvvm icommand relaycommand

当我实现ICommand接口时,会创建以下方法

#region ICommand Members

    public bool CanExecute(object parameter)
    {
    }

    public event EventHandler CanExecuteChanged;

    public void Execute(object parameter)
    {
    }

#endregion

有趣的部分是

public void Execute(object parameter)
{
}

只是因为它表明它需要1个参数。如果我不需要传递参数怎么办?在我的ViewModel中,我有以下代码

public class DownloadViewModel : BaseViewModel
{
    public ICommand BrowseForFile { get; set; }

    public string File { get; set; }

    public DownloadViewModel()
    {
        BrowseForFile = new RelayCommand(new Action<object>(OpenDialog));
    }

    private void OpenDialog(object o)
    {
        var dialog = new System.Windows.Forms.FolderBrowserDialog();
        System.Windows.Forms.DialogResult result = dialog.ShowDialog();
        File = dialog.SelectedPath;
    }
}

OpenDialog方法不需要参数,但看起来好像我必须这样才能满足接口。

我这样做是对吗还是我错过了这一点?

2 个答案:

答案 0 :(得分:2)

Execute获取参数的事实与ViewModel中的方法无关。影响OpenDialog所需参数的唯一因素是ICommand的实现。

如果您的实施是,例如:

public class MyRandomCommand : ICommand
{
    private readonly Action _action;

    public MyRandomCommand(Action action)
    {
        _action = action;
    }

    public void Execute(object parameter)
    {
        _action();
    }

    ...
}

然后您的OpenDialog方法不需要任何参数,因为您可以按如下方式创建命令:

public ICommand Command { get { return new MyRandomCommand(OpenDialog); } }

但是,您可以根据要传递给命令的方法要求任何您喜欢的签名。

RelayCommand最常见,现成的实现可以采用0或1参数的方法,并且会从Execute适当地调用。

答案 1 :(得分:2)

是的,ICommand始终需要一个对象和RelayCommand。如果你不需要它,你传递null并且不要在你的方法中使用它,这是丑陋的。

我会使用Prism的DelegateCommand代替。这存在于非泛型版本中,不带参数:

Command = new DelegateCommand(DoSomething);
CommandWithParameter = new DelegateCommand<int>(DoSOmethingWithInt);

它在PRISM程序集中,您必须下载并参考。

using Microsoft.Practices.Prism;

PRISM

或者,使用MVVMLight工具包,它提供了一个基本相同的命令类。无论如何,在没有MVVM框架的情况下使用MVVM毫无意义。我可以推荐PRISM,也可以推荐DelegateCommandEventAggregator等基本内容。