Передача параметров команде 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.
надеюсь, что это поможет вам или любому, кто проходит мимо