Передача параметров команде MVVM

кто-нибудь знает, как передать параметры Command используя CommandHandler? Предположим, я хотел бы передать строковое жестко закодированное значение из XAML. Я знаю, как передать из XAML, но не как обработать его в коде MVVM позади. Код ниже отлично работает, если нет необходимости передавать какие-либо параметры.

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();
    }
}

4 ответов


вам нужно изменить две вещи

1.Измените свой Commandhandler принять параметр

 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.Изменить способ признать 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;
}

вы должны просто записать свою строку в CommandParameter:

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

и меняем от:

private Action _action;
private bool _canExecute;

разрешить принимать параметры:

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

предполагая, что вы используете RelayCommand в параметре obj метод DoSmth будет "Привет":

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

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

параметр передается в ICommand.Execute метод, вам просто нужно передать его своему обработчику.

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);
    }
}

на это уже был дан ответ, но вы можете не знать, что есть некоторые рамки, чтобы избежать шаблонного кода, связанного с командами (и INotifyPropertyChanged) в MVVM.

одним из самых известных является MVVM свет, который будет обрабатывать несколько вещей для вас.

используя эту структуру, вот как вы обрабатываете команду с параметрами:

(Примечание: мы собираемся создать команду, которая изменила отображаемый UserControl, как UserControl является "основной частью" приложения)

1) в ViewModel определите RelayCommand с типом аргумента (в данном случае UserControl)

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

2) Определите метод, который будет привязан к команде (упрощено здесь)

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

3) привязать команду к методу, который вы только что определили

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

теперь ваша команда настроена и готова к использованию в вашем XAML, предположим, вы хотите переключить страницу с выбором меню для образец...

4) команда привязки с параметром к элементам управления (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>

Примечание: pageManager-это просто класс, который инициализирует все мои страницы в их состояния по умолчанию, очевидно, есть ссылка на него в моей ViewModel.

надеюсь, что это поможет вам или любому, кто проходит мимо