2009-05-22 3 views
0

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

Код ниже выглядит так, как будто он соответствует требуемому синтаксису, но 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

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

Конструкторы для команды реле принимают Action delegate и необязательно Predicate delegate. Эти делегаты не принимают 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); 
} 



EDIT (Добавлено из обсуждения в комментариях):

Если вы хотите использовать что-то больше похоже на RoutedCommands, что сделает ViewModels больше зависят от конкретных представлений WPF, есть некоторые хорошие варианты.

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

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

+1

Спасибо, rmoore. Итак, правильно ли я понимаю, что если мне нужно получить доступ к EventArgs в вызываемом методе, я не могу использовать класс RelayCommand для его вызова? + tom –

+0

Правильно, основная ICommand не реализует каких-либо событий, на самом деле, насколько мне известно, RoutedCommand, они на самом деле происходят из чего-то, называемого CommandBinding, и это то, что ищет RoutedCommand. Я добавил некоторую дополнительную информацию для RoutedCommands в MVVM на свой пост, так как в этом комментарии недостаточно места =) – rmoore

+0

Спасибо большое! +10 ... –

3

В этот уик-энд (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; 
    } 
+0

Спасибо за информацию, jasonD. Я отказался от кода Джоша Смита в пользу нового шаблона проекта MV MVM MVKM Toolkit 0.1 Visual Studio, который мне очень нравится. Он прост в использовании и имеет очень хорошую документацию. См. Http://wpf.codeplex.com/Wiki/View.aspx?title=WPF%20Model-View-ViewModel%20Toolkit. –

Смежные вопросы