这是关于MVVM模式最佳实践的特定问题。我正在使用MvvmLight库。 它是这样的: 我的模型,说“飞行”,实现了一些业务逻辑,可以通过方法启动,暂停和停止飞行。无论是停止还是暂停飞行,每种方法都会使其功能发生。一个重要的变量是状态枚举,表示航班状态 - 播放,停止或暂停。如上所述,状态变量(和属性)在模型中定义。 另一方面,航班类由一个ViewModel类包装,该类包含一个包裹飞行模型中状态变量的Status属性,以及连接到飞行模型播放停止暂停方法的RelayCommands。
问题在于: 当我通过视图执行其中一个命令时,它会执行模型中的方法,以便状态变量本身直接更改,但它只会在模型中更改.ViewModel中的status属性不知道包装的变量已被更改,因为它已直接更改...这意味着如果某个视图元素绑定到status属性,它将不会在命令执行时更改..
我知道有几种方法可以解决这个问题,但我要求一个不会破坏MVVM模式的公平解决方案(比如在模型的飞行课中使用INotifyPropertyChanged)
答案 0 :(得分:5)
这类问题没有灵丹妙药解决方案。您的ViewModel和Model需要以允许信息传播到View的方式进行设计;如果这是不可能的,那么设计是有缺陷的,需要改变。
以下是您应该研究的几件事:
RelayCommand
s。INotifyPropertyChanged
来完成。答案 1 :(得分:4)
如上所述,您的ViewModel应按以下方式包装Model:
class Model
{
public int State{get;private set;}
public void Fly()
{
State=1;
}
public void Stop()
{
State = 2;
}
}
class ViewModel : ViewModelBase
{
int State{ get{ Model.State;}}
...
OnFlyCommand()
{
Model.Fly();
NotifyPropertyChanged("State");
}
}
答案 2 :(得分:3)
您可以在ViewModel在Model上执行方法后立即调用OnNotifyPropertyChanged。这不是很优雅,但如果不重构你的Model类,你就不会变得更简单。
答案 3 :(得分:1)
最佳做法是从命令执行调用viewmodel,而不是从viewmodel调用模型更改,之后将viewmodel状态标记为已更改
答案 4 :(得分:1)
执行命令后,您知道哪些属性已更改?我的意思是,您是否可以明确提出特定属性集的更改通知,或者修改后的属性集正在发生变化?
在前一种情况下,您可以调用命令并显式提升这些属性的事件:
command.Execute();
NotifyPropertyChanged("PropA");
...
NotifyPropertyChanged("PropN");
在第二种情况下,您可以使用反射为Model
类的每个属性引发更改通知事件,或者您可以使用更智能的解决方案,如PostSharp.Domain.Toolkit。