案例
假设我有一个 Person
类、一个 PersonViewModel
和一个 PersonView
。
将属性从 PersonView
更新到 Person
模型非常简单。 PersonViewModel
包含一个 Person
对象并具有 PersonView
绑定(bind)到的公共(public)属性以更新 Person 模型。
但是。
假设 Person
模型可以通过 Service
进行更新。现在需要将属性更改传达给 PersonViewModel
,然后再传达给 PersonView
。
这就是我要解决的问题:
对于 Person
模型上的每个属性,我都会引发 PropertyChanged 事件。 PersonViewModel
订阅了 Person
的 PropertyChanged 事件。 PersonViewModel
将引发另一个 PropertyChanged 以更新 PersonView
。
这对我来说似乎是最明显的方式,但我有点想把这个问题抛出,希望有人能告诉我更好的方式。真的这么简单还是有更好的方法来将模型标记为已修改并更新 ViewModel 上的相应属性?
添加
PersonView
的 DataContext 是 PersonViewModel
。 Person
从 JSON 中获取并在其生命周期内多次更新。
欢迎针对我的特定案例提出架构更改建议。
回答
我将 aqwert 标记为我的问题的答案,因为它为我提供了我已经提出的解决方案的替代方案。
最佳答案
当 View 直接绑定(bind)到模型时(当 ViewModel 公开模型时也是这种情况),您正在混合 UI 代码和数据代码。 MVVM 的目标是将这两个代码域分开。这就是 ViewModel 的用途。
View 模型必须具有 View 可以绑定(bind)到的自己的属性。一个例子:
class PersonViewModel
{
private Person OriginalModel { get; set; }
public ValueViewModel<string> Name { get; set; }
public ValueViewModel<int> Postcode { get; set; }
protected void ReadFromModel(Person person)
{
OriginalModel = person;
Name.Value = OriginalModel.Name;
Postcode.Value = OriginalModel.Postcode;
}
protected Person WriteToModel()
{
OriginalModel.Name = Name.Value; //...
return OriginalModel;
}
}
使用这样的 ViewModel 设计确实可以将数据对象与用户界面代码分开。当 Person 类的结构改变时,UI 不需要相应地适应,因为 ViewModel 将它们彼此分开。
现在回答你的问题。正如你在上面的例子中看到的,我使用了一个通用的 ValueViewModel<T>
.此类实现 INotifyPropertyChanged
(和其他一些东西)。当您收到新的 Person
例如,您只需调用 ReadFromModel(newPerson)
在您的 ViewModel 上更新 UI,因为 View 绑定(bind)到的 ValueViewModel 会在其值更改时通知 UI。
这里是 ValueViewModel
的内部结构的极其简化的示例:
class ValueViewModel<T> : INotifyPropertyChanged
{
private T _value;
public T Value
{
get { return _value;}
set
{
_value = value;
RaisePropertyChanged("Value");
}
}
}
这是我们在 MVVM 库中使用的方法。它的优势在于它迫使开发人员将代码与设计人员的关注点明确分开。而且,作为副作用,它会在您的所有 View 和 View 模型中生成标准化的代码布局,从而提高代码质量。
关于c# - MVVM:修改模型,如何正确更新ViewModel和View?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10324009/