Silverlight MVVM 连接模型和视图模型

6

在MVVM方面有很多很好的例子,但我仍然感到困惑。

假设你有一个CustomerModel和一个CustomerViewModel。似乎CustomerModel上会有一个Name属性,而CustomerViewModel上也会有一个Name属性。 CustomerViewModel上的setter将设置CustomerModel Name属性,然后调用OnPropertyChanged(PropName)以便UI更新。这真的对吗?看起来getter/setters将被定义两次。如果您有一个具有50个属性的模型,那么这将变得非常繁琐。

此外,假设我设置了一个Qty属性。 ViewModel更新Model。 Model根据新的Qty更新其Value属性。 ViewModel如何被通知Model属性已更改?

3个回答

5

你的ViewModel并不一定要严格封装Model。在这种情况下,CustomerViewModel可能会有一个Customer属性,最终意味着你的View通过ViewModel绑定到Model属性……这是完全合法的。然而,封装它通常会带来好处。你的业务模型可能不包括变更通知。你可能不希望用户交互修改业务模型,直到用户点击了“确认”按钮。你的业务模型可能会因为错误输入而抛出异常,而你希望使用其他形式的验证。我相信你还可以想到其他的事情。实际上,我猜大部分时间你都想要封装它,所以它并不是写许多无意义的转发方法的“乏味”。


2
在你提供的客户示例中,CustomerModel 包含数据库(或其他后端)存储的所有信息。如果要在 UI 上显示(例如名称等),CustomerViewModel 包含类似的信息,但使用 INotifyPropertyChanged 接口将它们显示为 View(即 XAML)可以绑定到的属性。可能有 50 个其他属性,如果你有一个大的类。
public int Name
{
    get
    {
        return this.name;
    }

    set
    {
        if (this.name!= value)
        {
            this.name= value;
            this.OnPropertyChanged("Name");
        }
    }
}

ViewModel还包含其他UI状态的位 - 可见性标志,当前选项卡索引,由多个字段中的数据构建的更复杂的文本位,ObservableCollection<>的子项等。所有这些都可以绑定到XAML。

我曾经看到过将ViewModel从Model创建为一次性的、单向的过程,例如使用构造函数:

  CustomerViewModel viewModel = new CustomerViewModel(customer);

或者作为扩展方法。
  CustomerViewModel viewModel = customer.ToViewModel();

我没有看到更新ViewModel以响应Model更改的任何规定 - ViewModel的重点是与Model隔离。它保留数据的单独副本。它不会将更改传播回模型,除非您按下“保存”按钮。因此,如果您取消操作,模型中的内容没有更改,也没有可以撤消的内容。
您可能过于努力使ViewModel与Model保持同步 - 大多数情况下,例如保存或加载,您可以仅丢弃当前的ViewModel,并从模型的当前状态创建一个新的ViewModel。您需要保留ViewModel的UI状态并在其中更改数据吗?这不是常见的要求,但是可以通过在保存或加载时调用一两个方法来完成。
因此,还有假设这种连接逻辑发生在某个地方。这就是为什么大多数涉及视图的模式也涉及负责执行命令(例如显示客户,保存客户)并设置新UI状态的控制器的原因。

如果您将ViewModel与Model分开,那么如何应用Model中的任何规则呢?假设我有一个包含Qty和Value的Model。如果我在ViewModel上更改了Qty,那么应该将其传递到Model中,Model会根据新的Qty更新Value。现在,ViewModel应该显示新的Value。 - tkd
如果我在ViewModel上更改了Qty,那么它应该流经模型。但是,在您按下保存按钮或类似按钮之前,不会更新。当您这样做时,处理程序应更新模型,将其持久化并基于新的模型状态创建一个新的ViewModel。 - Anthony
那么,如果它没有流经模型,那么ViewModel如何获得更新后的Value字段呢?如果我更改了Qty,作为用户,我希望看到新的Value。MV没有计算Value的业务逻辑,只有Model才有。 - tkd

0

具体如何实现,部分取决于您的业务模型,正如wekempf已经说明的那样。

根据您在UI中显示客户信息的方式,您的ViewModel中可能有一个Customer(您的模型)类型的ObservableCollection。例如,如果您正在显示主/细节场景,其中您可能有客户列表,并在选择特定客户时显示下面的详细信息。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接