RelayCommand lambda语法问题

时间:2009-05-22 23:40:15

标签: mvvm lambda relaycommand

我正在为Josh Smith应用MVVM模式并遇到困难。我一直在研究这个问题,似乎无法使语法正确。

下面的代码看起来像它遵循所需的语法,但Visual Studio报告错误“委托'System.Action'在指示的行上不带'2'参数”

有人能看到我犯错的地方吗?谢谢!
+汤姆

    RelayCommand _relayCommand_MoveUp;
    public ICommand RelayCommand_MoveUp
    {
      get
      {
        if (_relayCommand_MoveUp == null)
        {
          _relayCommand_MoveUp = new RelayCommand(
          (sender, e) => this.Execute_MoveUp(sender, e),     **ERROR REPORTED HERE**
          (sender, e) => this.CanExecute_MoveUp(sender, e));
          return _relayCommand_MoveUp;
        }
      }
    }

    private void Execute_MoveUp(object sender, ExecutedRoutedEventArgs e)
    {
      if (_selectedFolder != null)
      {
        _selectedFolder.SelectParent();
      }
    }

    private void CanExecute_MoveUp(object sender, CanExecuteRoutedEventArgs e)
    {
      e.CanExecute = (_selectedFolder != null) && (_selectedFolder.Parent != null);
        }


//And from Josh Smith:

  public class RelayCommand : ICommand
  {
    public RelayCommand(Action<object> execute);
    public RelayCommand(Action<object> execute, Predicate<object> canExecute);

    public event EventHandler CanExecuteChanged;

    [DebuggerStepThrough]
    public bool CanExecute(object parameter);
    public void Execute(object parameter);
  }

2 个答案:

答案 0 :(得分:3)

本周末(8月22日)Josh Smith为他的MvvmFoundation项目检查了对codeplex的新更改,该项目改变了RelayCommand为具有参数的委托工作的方式。小心!

要将参数传递给委托,您需要使用他的新RelayCommand&lt; T&gt;改为构造函数:

    public ICommand GotoRegionCommand
    {
        get
        {
            if (_gotoRegionCommand == null)
                _gotoRegionCommand = new RelayCommand<String>(GotoRegionCommandWithParameter);
            return _gotoRegionCommand;
        }
    }
    private void GotoRegionCommandWithParameter(object param)
    {
        var str = param as string;
    }

答案 1 :(得分:2)

RelayCommand不是RoutedCommand,我认为这是你最终感到困惑的地方。

Relay命令的构造函数采用Action delegate和可选Predicate delegate。这些委托不接受EventArgs,只接受单个Object参数,这就是您遇到错误的原因。谓词还需要返回类型的bool,这是你将得到的下一个错误。在CanExecute谓词中,而不是像使用RoutedCommand那样设置e.CanExecute,只需返回true / false。

以下是它的外观:

public ICommand RelayCommand_MoveUp
{
  get
  {
    if (_relayCommand_MoveUp == null)
    {
      _relayCommand_MoveUp = new RelayCommand(Execute_MoveUp, CanExecute_MoveUp);

    }
    return _relayCommand_MoveUp;
  }
}

private void Execute_MoveUp(object sender)
{
  if (_selectedFolder != null)
  {
    _selectedFolder.SelectParent();
  }
}

private void CanExecute_MoveUp(object sender)
{
  return (_selectedFolder != null) && (_selectedFolder.Parent != null);
}



编辑(在评论中的讨论中添加):

如果你想使用更像RoutedCommands的东西,这将使ViewModel更依赖于WPF特定的视图,那么有一些很好的选择。

这个discussion完全可以将RoutedCommands与MVVM一起使用。

here's是Josh Smith和Bill Kempf提出的问题的一个非常可靠的解决方案。