Question

Je demande le motif MVVM par Josh Smith et la difficulté. J'ai fait des recherches sur le problème ici et ne peut pas sembler obtenir la syntaxe tout à fait raison.

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

Quelqu'un peut 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);
  }
Était-ce utile?

La solution

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

Les constructeurs pour la commande de relais prennent un délégué d'action option prédicats délégué . Ces délégués ne prennent pas EventArgs, juste le seul paramètre de l'objet, ce qui est la raison pour laquelle vous rencontrez une erreur. Le prédicat exige é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 vous le faites avec un RoutedCommand vous revenez tout simplement vrai / faux.

Voilà comment cela devrait ressembler à:

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, ce qui rendra les ViewModels plus dépendants des vues spécifiques WPF, il y a quelques bonnes options disponibles.

a toute idée d'utiliser RoutedCommands conjointement avec MVVM a commencé.

est une solution très solide aux questions présentées par Josh Smith et Bill Kempf.

Autres conseils

Ce week-end (22 Août) Josh Smith vérifié dans de nouveaux changements dans CodePlex pour son projet MvvmFoundation qui modifie la façon dont fonctionne RelayCommand pour les délégués avec un paramètre. Méfiez-vous!

Pour passer un paramètre au délégué, vous aurez besoin d'utiliser son nouveau constructeur RelayCommand à 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;
    }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top