在我们的WPF/MVVM应用程序中,我们直接绑定到Model
的属性,因为Model
来自旧库(我们在Model
类中添加了对INotifyPropertyChanged
的支持)。例如,ViewModel
的代码看起来像
Public Class MyViewModel
Inherits ViewModelBase
Public Property Model As MyModel
End Class
然后绑定是这样的:
<TextBox Text="{Binding Model.Prop1}" />
一切都工作得很好,直到我有这个要求在ViewModel
中有一些属性依赖于Model.Prop1
。具体来说,我将一个ComboBox
的ItemSource
绑定到ViewModel
中的集合属性,并且每当Model.Prop1
更改时,应该刷新/重新计算该集合。代码看起来像这样:
<ComboBox ItemsSource="{Binding MyCollection}" />
我有一些选择,但在我看来不是很好:
- 我可以让
Model
类持有ViewModel
的引用。在Model
的Prop1的setter中,我更新了ViewModel
的mycollection属性。当然这不是一个好主意 -
Model
和ViewModel
通信使用EventAggregator
。在我看来效率不高,而且我也需要在Model
类中做出重大改变。 - 让
ViewModel
有一个属性Prop1
并绑定到它。在它的getter中返回Model。在setter中赋值ModelProp1 = Value
。这是我目前的解决方案,但有一个问题:在我们的Model
中,我们有其他有用的属性/属性,我们基于此属性/属性创建了一个通用的Style
。例如,当模型。Prop1被改变了,Model
类中的另一个属性IsDirty
被设置为True
,在View
中我们改变了颜色。但是如果我们使用ViewModel
的Prop1,而不是Model
,我们就会像其他属性一样失去Style
的常见行为。
所以现在我仍然想使用绑定到{Binding Model.Prop1}
(不在ViewModel
中创建包装器属性),但以某种方式通知Model
中的其他属性,当它被改变时。我可以这么做吗?
您说我们在Model类中添加了对INotifyPropertyChanged
的支持。现在,如果这意味着您扩展或添加了原始类,并从每个属性添加了对INotifyPropertyChanged.PropertyChanged
事件的调用,那么您可以轻松地发现使用该事件更改了哪个属性:
Model.PropertyChanged += Model_PropertyChanged;
然后在PropertyChanged
处理程序中:
private void Model_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "Prop1")
{
// The Prop1 property value has changed
RefreshYourCollection();
}
}
然而,如果通过我们将INotifyPropertyChanged
的支持添加到模型类,您的意思是您的视图模型实现了INotifyPropertyChanged
接口,那么在现实中,您有没有将INotifyPropertyChanged
接口的支持添加到Model
类,您不能这样做。
如果是这种情况,那么首先需要为类中的每个相关属性正确地实现INotifyPropertyChanged
接口。如果您不能更改原始类,那么您应该在正确实现INotifyPropertyChanged
接口的类中扩展它,并将原始类的每个属性公开为新属性,以正确通知INotifyPropertyChanged
接口。
首先,我不喜欢Navigation Property
像Model.Prop1
一样,因为你最终会遇到这样简单的问题。
你所要做的就是创建一个ViewModel
,你只需要在UI
中显示,并从那里包装Model
的属性。
-
你甚至不需要聚合器或消息服务来更新它。刷新问题应该在
ViewModel
中处理,而不是在Model
中处理,我强烈反对model
应该听事件 -
我要去这个但是就像我开始说的那样,把你需要的东西放在
UI
中包括其他有用的属性也就是说,当Model.Prop1
被改变时在ViewModel.Prop1
的setter中它会更新Model
中的IsDirty
我不喜欢这个主意。请记住,这里的Model
并不意味着它是来自Database
的实际实体。在我看来,ViewModel
对Model
有一个参考,它有需要在UI
中显示的属性。