MVVM上有很多很好的例子,但我仍然感到困惑。
假设您有CustomerModel和CustomerViewModel。似乎CustomerModel上有一个Name属性,CustomerViewModel上有一个。 CustomerViewModel上的setter将设置CustomerModel Name属性,然后调用OnPropertyChanged(PropName)以便UI更新。这是真的吗?似乎getter / setter将被定义两次。如果你有一个拥有50个属性的模型,那将会变得非常繁琐。
另外,假设我设置了一个Qty属性。 ViewModel更新模型。模型根据新的数量更新其Value属性。如何通知ViewModel Model属性发生了变化?
答案 0 :(得分:5)
您的ViewModel不必严格封装模型。在您的场景中,CustomerViewModel可能具有Customer属性,这最终意味着您的View绑定到Model属性......它只是通过ViewModel实现。那是完全合法的。也就是说,封装它通常是有益的。您的商业模式可能不包含变更通知。在用户单击“确定”按钮之前,您可能不希望用户交互修改业务模型。您的业务模型可能通过异常输入错误,而您希望使用其他形式的验证。我相信你能想到其他的事情。事实上,我猜大多数时候你都想要封装,所以在编写大量无意义的中继方法时,它并不是真的“乏味”。
答案 1 :(得分:2)
在您提供的客户示例中,CustomerModel包含数据库(或其他后端)存储的所有信息。 CustomerViewModel包含类似的信息,如果它将显示在UI(名称等,如果你有一个大类,可能还有50个其他属性),但使用INotifyPropertyChanged接口将它们显示为View(即XAML)可以的属性绑定到。
e.g。
public int Name
{
get
{
return this.name;
}
set
{
if (this.name!= value)
{
this.name= value;
this.OnPropertyChanged("Name");
}
}
}
ViewModel还包含其他UI状态位 - 可见性标记,当前Tab索引,由多个字段中的数据构建的更复杂的文本位,ObservableCollection<>儿童用品等等。所有这些都与XAML绑定。
我已经看到从模型创建的ViewModel是一次性的单向过程,例如使用构造函数:
CustomerViewModel viewModel = new CustomerViewModel(customer);
或作为扩展方法
CustomerViewModel viewModel = customer.ToViewModel();
我没有看到更新ViewModel以更改模型的任何规定 - ViewModel的要点是它与模型隔离。它保留了数据的单独副本。它不会将更改传播回模型,直到您按下“保存”按钮。因此,如果取消,模型中的任何内容都不会发生变化,也无法撤消。
您可能正在努力使ViewModel与模型保持同步 - 大多数情况如保存或加载您只需丢弃当前的ViewModel并从模型的当前状态创建一个新的ViewModel。您是否需要保持ViewModel的UI状态并更改其中的数据?这不是常见的要求,但可以通过在保存或加载发生时调用的一个或两个方法来完成。
所以也有假设这个连线逻辑发生在某个地方。这就是为什么涉及视图的大多数模式还涉及控制器,它们负责对命令进行操作(例如,显示客户,保存客户)以及之后设置新的UI状态。
答案 2 :(得分:0)
具体如何完成,部分取决于wekempf已经说过的商业模式。
根据您在UI中显示客户信息的方式,您可能在ViewModel中有一个ObservableCollection Customer(您的模型)类型。例如,如果您正在显示主/详细方案,您可能会在其中显示客户列表,并在选择特定客户时显示以下详细信息。