Вопрос

Я применяю шаблон MVVM в соответствии с Джошем Смитом и испытываю трудности.Я исследовал проблему здесь и, похоже, не могу понять синтаксис совершенно правильно.

Приведенный ниже код выглядит для меня так, как будто он соответствует требуемому синтаксису, но Visual Studio сообщает об ошибке "Делегировать 'System.Действие' не принимает '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);
  }
Это было полезно?

Решение

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

Конструкторы для команды ретрансляции принимают Делегат действия и необязательный Делегат предиката.Эти делегаты не принимают EventArgs, только один параметр объекта, из-за чего вы сталкиваетесь с ошибкой.Для предиката также требуется возвращаемый тип 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, что сделает ViewModels более зависимыми от конкретных представлений WPF, есть несколько хороших доступных вариантов.

Это Обсуждение у меня появилась идея использовать RoutedCommands совместно с MVVM в целом.

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

Другие советы

В эти выходные (22 августа) Джош Смит внес новые изменения в codeplex для своего проекта MvvmFoundation, который изменяет способ работы 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;
    }
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top