2009-05-22 37 views
0

我正在爲每個Josh Smith應用MVVM模式並遇到困難。我一直在研究這個問題,似乎無法讓語法變得非常正確。RelayCommand lambda語法問題

下面的代碼在我看來像它遵循所需的語法,但Visual Studio報告錯誤「Delegate'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參數,這就是您遇到錯誤的原因。謂詞還需要一個返回類型的布爾值,這是您將得到的下一個錯誤。在CanExecute謂詞中,不像使用RoutedCommand那樣設置e.CanExecute,只需返回true/false。

下面是它應該是什麼樣子:

​​



EDIT(從討論中添加註釋):

如果你想要更多的使用類似RoutedCommands,這將使ViewModels更依賴於WPF特定的視圖,有一些很好的選項可用。

discussion了使用RoutedCommands結合MVVM開始的整體思路。

而且here's一個非常堅實的解決方案,由約什 - 史密斯和比爾·肯普夫提出的問題。

+1

謝謝,rmoore。那麼,我是否正確理解如果我需要訪問被調用方法中的EventArgs,我不能使用RelayCommand類來調用它? + tom – 2009-05-23 00:44:23

+0

沒錯,基本的ICommand並沒有實現任何事件,事實上,據我所知,RoutedCommand實際上來自於一個叫做CommandBinding的東西,這就是RoutedCommand尋找的東西。 我在MVVM中爲我的文章添加了一些附加信息,因爲這裏沒有足夠的空間=) – rmoore 2009-05-23 04:13:33

3

本週末(8月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; 
    }