5

MVVM 上有很多很好的例子,但我仍然很困惑。

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

另外,假设我设置了一个 Qty 属性。ViewModel 更新模型。模型根据新的数量更新其 Value 属性。ViewModel 如何收到 Model 属性更改的通知?

4

3 回答 3

5

您的 ViewModel 不必严格封装模型。在您的场景中,CustomerViewModel 可能有一个 Customer 属性,这最终意味着您的 View 绑定到 Model 属性......它只是通过 ViewModel 来实现的。这是完全合法的。然而,这就是说,封装它通常是有好处的。您的商业模式可能不包括变更通知。在用户单击 OK 按钮之前,您可能不希望用户交互修改业务模型。您的业​​务模型可能会通过错误输入的异常,而您想使用另一种形式的验证。我相信你可以想到其他事情。事实上,我猜大多数时候你会想要封装,所以它并不是真的“乏味”

于 2009-03-19T20:47:06.620 回答
2

在您提供的客户示例中,CustomerModel 包含您的数据库(或其他后端)存储的所有信息。如果将在 UI 上显示 CustomerViewModel 包含类似的信息(名称等,如果您有一个大类,可能还有 50 个其他属性),但使用 INotifyPropertyChanged 接口将它们显示为视图(即 XAML)可以的属性绑定到。

例如

public int Name
{
    get
    {
        return this.name;
    }

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

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

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

  CustomerViewModel viewModel = new CustomerViewModel(customer);

或作为扩展方法

  CustomerViewModel viewModel = customer.ToViewModel();

我还没有看到任何更新 ViewModel 以更改模型的规定 - ViewModel 的重点是它与模型隔离。它保留数据的单独副本。它不会将更改传播回模型,直到您按下“保存”按钮。因此,如果您改为取消,则模型中的任何内容都没有改变,也没有什么可以撤消的。

您可能过于努力地使 ViewModel 与模型保持同步 - 大多数情况下,例如保存或加载,您可以丢弃当前的 ViewModel 并从模型的当前状态创建一个新的。是否需要保留 ViewModel 的 UI 状态并更改其中的数据?这不是一个常见的要求,但可以通过在保存或加载发生时调用的一两个方法来完成。

所以也有这样的假设,即这种连线逻辑发生在某个地方。这就是为什么大多数涉及视图的模式还涉及控制器,这些控制器负责执行命令(例如显示客户、保存客户)并在之后设置新的 UI 状态。

于 2009-03-13T10:54:44.710 回答
0

正如wekempf已经说明的那样,具体如何完成将部分取决于您的商业模式。

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

于 2009-05-08T13:16:12.597 回答