命令MVVM(WPF) - 如何返回值?

时间:2010-02-10 20:18:42

标签: c# wpf mvvm

我现在一直在使用MVVM模式,但在现实生活中我仍遇到问题。这是另一个: 我使用命令和冒泡事件在ViewModel中处理。到现在为止还挺好。但是我使用MVVM的项目实际上是一个类库。一旦我运行命令代码,我需要能够将一个对象发送回调用应用程序。建议的方法是什么?

具体做法是: 在我的调用应用程序中,我有一个XAML页面直接绑定到库的ViewModel,它包含一个对象“Thing1”。单击按钮时,将调用ViewModel中的方法(将其称为“CopyThing1()”)。它复制“Thing1”以创建“Thing2”。然后我需要将“Thing2”发送回调用应用程序。

感谢!!!

4 个答案:

答案 0 :(得分:10)

命令不返回值,它们会更改应用程序的状态。如果ICommands附加到ViewModels,它非常简单,因为您可以通过在执行命令时改变ViewModel来实现这一点。

使用Josh Smith's excellent MVVM article中的RelayCommand:

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

答案 1 :(得分:2)

如果Thing2是您的viewmodel上的另一个属性,您可以使用普通的INotifyPropertyChanged来通知UI更改。

你也可以使用PrismEventAggregator来获得更加分离的方法

答案 2 :(得分:2)

理想的方法是定义一个从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将返回值。

答案 3 :(得分:1)

虽然关于命令的信息是清楚和正确的,但它无法在我的情况下应用,因为需要发生的响应是在一个不使用MVVM的调用应用程序中,它不是仅仅是UI响应。我对Prism进行了调查,但发现它太复杂了,我现在还不需要。我最终提高并处理事件,如此处所述 - &gt; WPF MVVM Correct Way to Fire Event on View From ViewModel