我是WPF / MVVM的新手,我发现的例子似乎并没有涵盖我所面临的问题。
我有一个用于管理相当复杂的业务配置对象的屏幕。在MVVM中,我认为这意味着我应该拥有以下内容:
在我的情况下,有业务规则说我的业务类fieldA的更改可能有各种副作用,例如更改fieldB的值,或填充整个子对象列表。
我可能是错的,但我认为我应该将这些规则封装在业务类中,因为这些规则并不像实体那样关乎屏幕。
当然,这些副作用需要立即回到屏幕上。
因此,从用户的角度来看,他可能会编辑fieldA,并在View上看到fieldB更新。
我理解如何从View到ViewModel数据绑定。
但在我的情况下,似乎我需要两层数据绑定:一个在View和ViewModel之间,另一个在ViewModel和Model之间。
鉴于我有两次基本相同的问题,我认为应该适用一种解决方案。所以我把我的Model类变成了DependencyObject,并且我把它的属性变成了DependencyProperties。
以fieldA为例,它将出现在所有三个层中:
我不想通过跳过第2部分将我的View XAML直接耦合到业务对象,这对我来说似乎不是一个干净的模式应用程序。也许这是错误的。
我基本上似乎需要在我的ViewModel中使用“传递DependencyProperty”。
我的问题:
答案 0 :(得分:1)
我自己也在努力解决这个问题,我想这对MVVM来说是一个非常普遍的障碍。我的回答是避免使用DependencyObject
或INotifyPropertyChanged
污染域名,因为它在某种程度上否定了使用ViewModel的有效性。
ViewModel的目标是以与特定视图相关的方式公开模型。当VM基本上需要公开整个域对象时,它会变得混乱。我将这些称为“编辑器”视图模型。这些是从域对象传递属性最诱人的。在这些情况下,我给VM一个域对象(组合)的引用,并通过getter和setter。如果UI需要刷新或显示验证错误,ViewModel将使用INotifyPropertyChanged
和IDataErrorInfo
而不是DependencyProperty
来通知UI。如果域引发验证错误,则VM会捕获它并将其准备到视图的数据错误信息详细信息中。
答案 1 :(得分:0)
我同意Steve的意见,您应避免在模型/域类中使用DependencyObject
和DependencyProperty
,并且视图模型类应采用INotifyPropertyChanged
和IDataErrorInfo
约束目的。
我想在你的视图模型类中添加它,我会避免使用DependencyProperty
,除了你需要在xaml逻辑中使用的属性,例如DataTrigger
s。
为了处理在模型层类中触发的更改,我还可以在视图模型类中引用模型/域对象,并像Steve提到的那样将getter和setter传递给模型/域类。我想补充一点,模型/域类需要引发一个视图模型类需要订阅的事件,以便可以根据更改在视图模型类中调用一个或多个属性的OnPropertyChanged()
发生在您的业务逻辑中。
答案 2 :(得分:0)
首先,我不建议对视图模型或模型使用依赖项属性(DP)。 DP是在设计时考虑了UI概念的属性,例如优先规则,DataContext
支持,默认值等。您在视图模型中不需要这些概念,因此您应该使用INotifyPropertyChanged
代替。
视图模型只是模型层的传递根本不会增加任何值。所以不要这样做!您不应该仅仅因为您认为应该将代码,结构或概念添加到代码中。简单是你应该一直努力的目标。
因此,如果您可以实现模型图层,只需将INotifyPropertyChanged
绑定到您的视图即可。
但是......在某些情况下,您可能无法在模型中实施INotifyPropertyChanged
。例如,它可能是从Web服务生成的。在这种情况下,您将需要一个执行传递功能的视图模型,还需要通过INotifyPropertyChanged
添加更改通知。