2009-05-22 7 views
0

J'applique le modèle MVVM par Josh Smith et j'ai de la difficulté. J'ai recherché le problème ici et ne peux pas sembler avoir la syntaxe tout à fait raison.RelayCommand problème de syntaxe lambda

Le code ci-dessous ressemble à moi comme il suit la syntaxe requise, mais les rapports Visual Studio erreur « délégué « System.Action » ne prend pas d'arguments « 2 » » sur la ligne indiquée.

Quelqu'un peut-il voir où je fais une erreur? Merci!
+ 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); 
    } 

Répondre

2

Le RelayCommand est pas un RoutedCommand, que je pense est l'endroit où vous se retrouver confus.

Les constructeurs de la commande Relay prennent un Action delegate et un Predicate delegate facultatif. Ces délégués ne prennent pas EventArgs, juste le seul paramètre Object, ce qui explique pourquoi vous rencontrez une erreur. Le prédicat nécessite également un type de retour de bool, qui est la prochaine erreur que vous obtiendrez. Dans le prédicat CanExecute au lieu de définir e.CanExecute comme avec une commande RoutedCommand, vous renvoyez simplement true/false.

Voilà comment le résultat:

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 (Ajouté de la discussion dans les commentaires):

Si vous voulez utiliser quelque chose comme les RoutedCommands, qui fera la ViewModels dépend davantage des vues spécifiques à WPF, il y a quelques bonnes options disponibles.

Cette discussion a eu l'idée d'utiliser RoutedCommands conjointement avec MVVM démarré.

Et here's une solution très solide aux problèmes présentés par Josh Smith et Bill Kempf.

+1

Merci, rmoore. Alors, est-ce que je comprends bien que si j'ai besoin d'accéder à EventArgs dans la méthode appelée, je ne peux pas utiliser la classe RelayCommand pour l'appeler? + tom –

+0

C'est vrai, l'ICommand de base n'implémente aucun évènement, en fait, ni à ma connaissance le RoutedCommand, ceux-ci viennent réellement de quelque chose appelé CommandBinding, ce que recherche la RoutedCommand. J'ai ajouté quelques informations supplémentaires pour RoutedCommands dans MVVM à mon poste, car il n'y a pas assez de place dans ce commentaire =) – rmoore

+0

Merci beaucoup! +10 ... –

3

Ce week-end (22 août) Josh Smith a vérifié les nouveaux changements dans codeplex pour son projet MvvmFoundation qui change la façon dont RelayCommand fonctionne pour les délégués avec un paramètre. Il faut se méfier!

Pour passer un paramètre au délégué, vous aurez besoin d'utiliser son nouveau RelayCommand <T> constructeur à la place:

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

Merci pour l'info, jasonD. J'ai abandonné le code de Josh Smith en faveur du nouveau modèle de projet MS MVVM Toolkit 0.1 Visual Studio, dont je suis * très * satisfait. Il est facile à utiliser et a une très bonne documentation. Voir http://wpf.codeplex.com/Wiki/View.aspx?title=WPF%20Model-View-ViewModel%20Toolkit. –

Questions connexes