0

我正在应用 Josh Smith 的 MVVM 模式并且遇到了困难。我一直在这里研究这个问题,但似乎无法完全正确地使用语法。

在我看来,下面的代码遵循了所需的语法,但 Visual Studio 在指示的行上报告错误“Delegate 'System.Action' does not take '2' arguments”

有人可以看到我在哪里犯了错误吗?谢谢!
+汤姆

    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);
  }
4

2 回答 2

3

本周末(8 月 22 日)Josh Smith 为他的 MvvmFoundation 项目在 codeplex 中签入了新的更改,该项目更改了 RelayCommand 为具有参数的代表工作的方式。谨防!

要将参数传递给委托,您需要使用他的新 RelayCommand<T> 构造函数:

    public ICommand GotoRegionCommand
    {
        get
        {
            if (_gotoRegionCommand == null)
                _gotoRegionCommand = new RelayCommand<String>(GotoRegionCommandWithParameter);
            return _gotoRegionCommand;
        }
    }
    private void GotoRegionCommandWithParameter(object param)
    {
        var str = param as string;
    }
于 2009-08-25T04:35:39.440 回答
2

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

Relay 命令的构造函数采用Action 委托和可选的Predicate 委托。这些委托不采用 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 的东西,这将使 ViewModels 更依赖于 WPF 特定视图,有一些不错的选项可用。

这个讨论开始了将 RoutedCommands 与 MVVM 结合使用的整个想法。

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

于 2009-05-22T23:58:59.077 回答