RelayCommand лямбда-синтаксис проблема - PullRequest
0 голосов
/ 23 мая 2009

Я применяю шаблон 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 ]

3 голосов
/ 25 августа 2009

В эти выходные (22 августа) Джош Смит зарегистрировал новые изменения в codeplex для своего проекта MvvmFoundation, который меняет способ работы 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;
    }
2 голосов
/ 23 мая 2009

RelayCommand - это не RoutedCommand, и я думаю, это то, что вы запутались.

Конструкторы для команды Relay принимают делегат действия и необязательный делегат предиката . Эти делегаты не принимают EventArgs, а только один параметр Object, поэтому вы сталкиваетесь с ошибкой. Предикат также требует тип возврата bool, который является следующей ошибкой, которую вы получите. В предикате CanExecute вместо установки e.CanExecute, как вы делаете с RoutedCommand, вы просто возвращаете 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, есть несколько хороших доступных вариантов.

В этом обсуждении началась вся идея использования RoutedCommands в сочетании с MVVM.

И вот очень солидное решение проблем, представленных Джошем Смитом и Биллом Кемпфом.

...