Командование в MVVM (WPF)--как вернуть значение?
Я использую шаблон MVVM уже некоторое время, но я все еще сталкиваюсь с проблемами в реальных ситуациях. Вот еще один: Я использую командование и пузырь вверх событие, которое будет обрабатываться в ViewModel. Пока все идет хорошо. Но проект, для которого я использую MVVM, на самом деле является библиотекой классов. После запуска кода команды мне нужно иметь возможность отправить объект обратно в вызывающее приложение. Какие предлагаются способы сделать это?
специально: В мое призвание приложение на XAML страница, привязанная непосредственно к ViewModel библиотеки, которая содержит объект "Thing1". При нажатии кнопки вызывается метод в ViewModel (назовите его "CopyThing1()"). Он копирует "Thing1" создать "Thing2". Затем мне нужно отправить "Thing2" обратно в вызывающее приложение.
спасибо!!!
4 ответов
команды не возвращают значения, они изменяют состояние приложения. В случае ICommands, прикрепленных к ViewModels, это довольно просто, потому что вы можете сделать это, просто изменив ViewModel при выполнении команды.
использование RelayCommand от отличная статья MVVM Джоша Смита:
public class MyViewModel : INotifyPropertyChanged
{
private readonly ICommand mutateCommand;
private Thing thing;
public MyViewModel()
{
this.mutateCommand = new RelayCommand(this.Mutate);
}
public ICommand MutateCommand
{
get { return this.mutateCommand; }
}
public Thing Thing
{
get { return this.thing; }
set
{
this.thing = value;
// raise PropertyChanged event here...
}
}
private void Mutate(object parameter)
{
this.Thing = new Thing();
}
}
после вызова myVM.MutateCommand.Execute(new object());
вы можете получить доступ к новому значению myVM.Thing
.
Если Thing2 является другим свойством viewmodel, вы можете использовать normal INotifyPropertyChanged для информирования пользовательского интерфейса об изменении.
вы также можете использовать Присм ' s EventAggregator
для более развязанного подхода
хотя информация о командовании была ясной и правильной, ее нельзя было применить в моем случае, потому что ответ, необходимый для этого, был в вызывающем приложении, не использующем MVVM, и он не должен был быть только ответом UI. Я исследовал Prism, но нашел его слишком сложным для того, что мне нужно в данный момент. Я закончил тем, что поднял и обработал события, как описано здесь ... > WPF MVVM правильный способ запуска события при просмотре из ViewModel
идеальным подходом является определение нового класса, унаследованного от ICommand следующим образом:
public abstract class Command2<T1, T2> : ICommand {
public abstract T2 Execute2(T1 parameter);
}
public class DelegateCommand2<T1, T2> : Command2<T1, T2> {
public DelegateCommand2(Func<T1, T2> execute, Predicate<T1> canExecute) {
_execute = execute;
_canExecute = canExecute;
}
public override T2 Execute2(T1 parameter) {
if (CanExecute(parameter) == false)
return default(T2);
else
return _execute((T1)parameter);
}
}
обратите внимание, что Execute2 возвращает значение так же, как обычная функция. Вот как его использовать.
private readonly ICommand _commandExample = new DelegateCommand2<int, Point3D>(
commandExample_Executed,
commandExample_CanExecute
);
public Command2<int, Point_3D> CommandExample {
get {
return (Command2<int, Point_3D>) _commandExample;
}
}
private static Point3D commandExample_Executed(int index) {
return Fun1(index); //Fun1 returns a Point_3D
}
private static bool commandExample_CanExecute(int index) {
return true;
}
вызывает Execute2 вместо Execute возвращает значение.