RelayCommand lambda relay syntax problem

I am using Josh Smith's MVVM pattern and am having difficulty. I've been researching the problem here and can't get the syntax completely correct.

The following code looks like it matches the required syntax, but Visual Studio reports the error "Delegate" System.Action "does not accept arguments" 2 " on the specified line. P>

Can anyone see where I am making the 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);
  }

      

0


a source to share


2 answers


The RelayCommand is not a RoutedCommand, which I think is where you end up confusing.

The constructors for the Relay command accept an action delegate and an optional predicate delegate . These delegates do not accept EventArgs, but only one Object parameter, which is why you ran into an error. The predicate also requires a bool return type, which is the next error you get. In the predicate CanExecute, instead of setting e.CanExecute as you do with RoutedCommand, you simply return true / false.

This is 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 akin to RoutedCommands, which makes the ViewModels more dependent on specific WPF views, there are some good options.

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

And here is a very solid solution to the problems posed by Josh Smith and Bill Kempf.

+2


a source


This weekend (Aug 22) Josh Smith checked out new Codeplex changes for his MvvmFoundation project, which changes the way RelayCommand works for parameterized delegates. Caution!

To pass a parameter to a delegate, you will need to use its new RelayCommand <T> 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;
    }

      

+3


a source







All Articles