Командование в MVVM (WPF) - как вернуть значение? - PullRequest
9 голосов
/ 10 февраля 2010

Я уже некоторое время использую паттерн MVVM, но все еще сталкиваюсь с проблемами в реальных ситуациях. Вот еще один: Я использую командование и всплывающее событие, которое будет обработано во ViewModel. Все идет нормально. Но проект, для которого я использую MVVM, на самом деле является библиотекой классов. После запуска кода команды я должен иметь возможность отправить объект обратно вызывающему приложению. Какие предлагаются способы сделать это?

В частности: В моем вызывающем приложении у меня есть страница XAML, привязанная непосредственно к ViewModel библиотеки, которая содержит объект «Thing1». При нажатии кнопки вызывается метод в ViewModel (назовите его «CopyThing1 ()»). Он копирует «Thing1» для создания «Thing2». Затем мне нужно отправить «Thing2» обратно в вызывающее приложение.

Спасибо !!!

Ответы [ 4 ]

10 голосов
/ 10 февраля 2010

Команды не возвращают значения, они изменяют состояние вашего приложения. В случае 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.

2 голосов
/ 09 января 2015

Идеальный подход - определить новый класс, унаследованный от 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 вернут значение.

2 голосов
/ 10 февраля 2010

Если Thing2 является другим свойством вашей модели представления, вы можете использовать обычный INotifyPropertyChanged для информирования пользовательского интерфейса об изменении.

Вы также можете использовать Prism EventAggregator для более свободного подхода

1 голос
/ 12 февраля 2010

Хотя информация о Командовании была четкой и правильной, ее нельзя было применить в моем случае, потому что ответ, который должен был произойти, был в вызывающем приложении, НЕ использующем MVVM, и это был не только ответ пользовательского интерфейса. Я исследовал Призму, но нашел ее слишком сложной для того, что мне нужно в данный момент. Я закончил поднимать и обрабатывать события, как описано здесь -> WPF MVVM Правильный способ запуска события при просмотре из ViewModel

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...