我现在一直在使用MVVM模式,但在现实生活中我仍遇到问题。这是另一个: 我使用命令和冒泡事件在ViewModel中处理。到现在为止还挺好。但是我使用MVVM的项目实际上是一个类库。一旦我运行命令代码,我需要能够将一个对象发送回调用应用程序。建议的方法是什么?
具体做法是: 在我的调用应用程序中,我有一个XAML页面直接绑定到库的ViewModel,它包含一个对象“Thing1”。单击按钮时,将调用ViewModel中的方法(将其称为“CopyThing1()”)。它复制“Thing1”以创建“Thing2”。然后我需要将“Thing2”发送回调用应用程序。
感谢!!!
答案 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更改。
你也可以使用Prism的EventAggregator
来获得更加分离的方法
答案 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