RelayCommand lambda 语法问题

发布于 2024-07-21 19:41:57 字数 1410 浏览 7 评论 0原文

我正在按照 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);
  }

I am applying the MVVM pattern per Josh Smith and having difficulty. I've been researching the problem here and can't seem to get the syntax quite right.

The code below looks to me like it follows the required syntax, but Visual Studio reports error "Delegate 'System.Action' does not take '2' arguments" on the line indicated.

Can someone see where I am making a mistake? Thanks!
+tom

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

合久必婚 2024-07-28 19:41:57

本周末(8 月 22 日)Josh Smith 在他的 MvvmFoundation 项目的 codeplex 中签入了新的更改,这改变了 RelayCommand 使用参数为委托工作的方式。 谨防!

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

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

This weekend (August 22) Josh Smith checked in new changes into codeplex for his MvvmFoundation project which changes the way RelayCommand works for delegates with a parameter. Beware!

To pass a parameter to the delegate, you'll need to use his new RelayCommand<T> constructor instead:

    public ICommand GotoRegionCommand
    {
        get
        {
            if (_gotoRegionCommand == null)
                _gotoRegionCommand = new RelayCommand<String>(GotoRegionCommandWithParameter);
            return _gotoRegionCommand;
        }
    }
    private void GotoRegionCommandWithParameter(object param)
    {
        var str = param as string;
    }
初见终念 2024-07-28 19:41:57

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

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

它应该是这样的:

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 特定视图,那么有一些不错的选项可用。

通过此讨论了解了使用RoutedCommands 与 MVVM 结合启动。

这里针对 Josh Smith 和 Bill Kempf 提出的问题提供了一个非常可靠的解决方案。

The RelayCommand isn't a RoutedCommand, which I think is where you ending up confused.

The constructors for the Relay command take an Action delegate and optional Predicate delegate. These delegates don't take an EventArgs, just the single Object parameter, which is why you are encountering an error. The predicate also requires a return type of bool, which is the next error you'll get. In the CanExecute predicate instead of setting e.CanExecute like you do with a RoutedCommand you simply return true/false.

Here's how it should look:

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

EDIT (Added from discussion in comments):

If you want to use something more like the RoutedCommands, which will make the ViewModels more dependent on WPF specific views, there are some good options available.

This discussion got the whole idea of using RoutedCommands in conjunction with MVVM started.

And here's a very solid solution to the issues presented by Josh Smith and Bill Kempf.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文