web-dev-qa-db-fra.com

Passer des paramètres à la commande MVVM

Quelqu'un sait-il comment passer des paramètres à Command en utilisant CommandHandler? Supposons que je souhaite transmettre une valeur codée en dur à partir de XAML. Je sais comment passer de XAML, mais pas comment le gérer dans le code MVVM derrière. Le code ci-dessous fonctionne bien s'il n'est pas nécessaire de passer de paramètres.

public ICommand AttachmentChecked
{
    get
    {
        return _attachmentChecked ?? (_attachmentChecked = new CommandHandler(() => ExecuteAttachmentChecked(), CanExecuteAttachmentChecked()));
    }
}

private void ExecuteAttachmentChecked()
{        
}

private bool CanExecuteAttachmentChecked()
{
    return true;
}

CommandHandler:

public class CommandHandler : ICommand
{
    private Action _action;
    private bool _canExecute;

    public CommandHandler(Action action, bool canExecute)
    {
        _action = action;
        _canExecute = canExecute;
    }

    public bool CanExecute(object parameter)
    {
        return _canExecute;
    }

    public event EventHandler CanExecuteChanged;

    public void Execute(object parameter)
    {
        _action();
    }
}
14
lucas

Vous devez changer deux choses

1.Changez votre Commandhandler pour accepter le paramètre

 public class CommandHandler : ICommand
{
    private Action<object> _action;
    private bool _canExecute;
    public CommandHandler(Action<object> action, bool canExecute)
    {
        _action = action;
        _canExecute = canExecute;
    }

    public bool CanExecute(object parameter)
    {
        return _canExecute;
    }

    public event EventHandler CanExecuteChanged;

    public void Execute(object parameter)
    {
        _action(parameter);
    }
}

2.Changez la méthode pour accepter le CommandParameter:

public ICommand AttachmentChecked
{
    get
    {
        return _attachmentChecked ?? (_attachmentChecked = new CommandHandler(param => ExecuteAttachmentChecked(param), CanExecuteAttachmentChecked()));
    }
}

private void ExecuteAttachmentChecked(object param)
{
 //param will the value of `CommandParameter` sent from Binding
}

private bool CanExecuteAttachmentChecked()
{
    return true;
}
12
Kylo Ren

Vous devez simplement écrire votre chaîne dans CommandParameter:

<Button Command="{Binding NextCommand}" 
CommandParameter="Hello" 
Content="Next" />

et changer de:

private Action _action;
private bool _canExecute;

pour autoriser l'acceptation des paramètres:

readonly Action<object> _execute;        
readonly Predicate<object> _canExecute;

En supposant que vous utilisez RelayCommand dans le paramètre obj de la méthode DoSmth sera "Bonjour":

public RelayCommand YourCommand { get; set; }
public YourViewModel()
{
    NextCommand = new RelayCommand(DoSmth);
}

private void DoSmth(object obj)
{
    Message.Box(obj.ToString()); 
}
10
StepUp

Cela a déjà été répondu, mais vous ne savez peut-être pas qu'il existe des cadres pour éviter le code passe-partout lié aux commandes (et INotifyPropertyChanged) dans MVVM.

L'un des plus célèbres est MVVM Light qui gérera quelques choses pour vous.

En utilisant ce cadre, voici comment vous gérez une commande avec des paramètres:

(Remarque: nous allons créer une commande qui a modifié le UserControl affiché, car le UserControl est la "partie principale" de l'application)

1) Dans votre ViewModel, définissez un RelayCommand avec le type d'argument (dans ce cas, un UserControl)

public RelayCommand<UserControl> changePageCommand { get; private set; }

2) Définissez la méthode à lier à la commande (simplifiée ici)

public void navigate(UserControl nextPage)
{
    currentUserControl = nextPage; 
}

3) Liez votre commande à la méthode que vous venez de définir

changePageCommand = new RelayCommand<UserControl>((page) => navigate(page));

Votre commande est maintenant toute configurée et prête à l'emploi dans votre XAML, disons que vous voulez changer de page avec des sélections de menu par exemple ...

4) Commande de liaison avec paramètre aux commandes (XAML)

<Menu>
    <MenuItem Header="_Pages">
        <MenuItem Header="_Account"
                  Command="{Binding changePageCommand}"
                  CommandParameter="{Binding pageManager.accountPage}" />
        <MenuItem Header="_Profile"
                  Command="{Binding changePageCommand}"
                  CommandParameter="{Binding pageManager.profilePage}" />
    </MenuItem>
</Menu>

Remarque: pageManager est simplement une classe qui initialise toutes mes pages à leurs états par défaut, il y a évidemment une référence à cela dans mon ViewModel.

J'espère que cela vous aidera, vous ou toute personne de passage,

7
Lionel Pire

Le paramètre est passé dans le ICommand.Execute, il vous suffit de la transmettre à votre gestionnaire.

public class CommandHandler : ICommand
{
    private Action<object> _action;
    private bool _canExecute;
    public CommandHandler(Action<object> action, bool canExecute)
    {
        _action = action;
        _canExecute = canExecute;
    }

    public bool CanExecute(object parameter)
    {
        return _canExecute;
    }

    public event EventHandler CanExecuteChanged;

    public void Execute(object parameter)
    {
        _action(parameter);
    }
}
6
Eldar Dordzhiev