ViewModel是否应该具有传递绑定到Model上的DependencyProperties的DependencyProperties?

5
我对WPF/MVVM不熟悉,我找到的示例似乎没有涵盖我面临的问题。在MVVM中,我认为我应该有以下内容:
1.几乎没有逻辑的XAML视图 2.具有屏幕逻辑的ViewModel类 3.我的业务类填充了Model角色,并具有所有业务逻辑
在我这种情况下,业务规则指出更改业务类的FieldA可能会产生各种副作用,例如更改FieldB的值或填充整个子对象列表。但我认为这些规则应该封装在业务类中,因为这些规则与实体相关,而不是与屏幕相关。自然地,这些副作用需要立即反映在屏幕上。
因此,从用户的角度来看,他可以编辑FieldA,并在View上看到FieldB的更新。我了解如何从View到ViewModel进行数据绑定。但在我的情况下,似乎我需要两个层次的数据绑定:一个在View和ViewModel之间,另一个在ViewModel和Model之间。
考虑到我基本上两次遇到相同的问题,我认为应该应用一种解决方案。因此,我将我的Model类转换为DependencyObject,并将其属性转换为DependencyProperties。例如,查看FieldA,它会出现在所有三个层面上:
1.作为一个视觉组件出现在View中,绑定到ViewModel.FieldA,例如text="{Binding FieldA, Mode=TwoWay}" 2.作为DependencyProperty绑定到ViewMode,向上绑定到View,向下绑定到Model 3.作为DependencyProperty出现在Model中
我不愿意通过跳过第2部分直接将我的View XAML与业务对象耦合在一起,因为这对我来说似乎不是一个干净的应用程序。也许这是错误的。因此,我似乎需要在ViewModel中使用“传递属性”的想法。
我的问题:
1.这是正确的一般方法还是我想错了? 2.是否有使用这种传递方法的示例? 3.有人能给出一个正确创建ViewModel和Model FieldA DependencyProperties之间传递绑定的代码示例吗?
3个回答

1

我自己曾经与这个问题纠结过,也想象过当涉及到MVVM时这是一个非常普遍的障碍。我的答案是要避免使DependencyObjectINotifyPropertyChanged污染领域,因为这有点否定了使用ViewModel的有效性。

ViewModel的目标是以适合特定视图的方式公开模型。当VM需要公开整个领域对象时,会变得混乱。我把这些称为“编辑器”视图模型。这些最容易通过从领域对象中传递属性来传递。在这些情况下,我将领域对象的引用(组合)传递给VM,并传递getter和setter。 ViewModel采用INotifyPropertyChangedIDataErrorInfo而不是DependencyProperty,以向UI发出信号,如果UI需要刷新或显示验证错误,则采用后两者。如果领域引发验证错误,则VM捕获它并将其准备成视图的数据错误信息细节。


0

我同意Steve的观点,你应该避免在你的模型/领域类中使用DependencyObjectDependencyProperty,而视图模型类应该采用INotifyPropertyChangedIDataErrorInfo进行绑定。

我想补充一点,在你的视图模型类中,除了需要在xaml逻辑中使用的属性(如DataTrigger)外,我会避免使用DependencyProperty

为了处理在模型层类中触发的更改,我还会在视图模型类中引用模型/领域对象,并像Steve提到的那样通过getter和setter传递给模型/领域类。我还要补充的是,模型/领域类需要引发一个事件,视图模型类需要订阅该事件,以便根据业务逻辑中发生的更改在视图模型类中调用一个或多个属性的OnPropertyChanged()方法。


0

首先,我不建议在视图模型或模型中使用依赖属性(DP)。DP是专为UI概念设计的属性,例如优先级规则、DataContext支持、默认值等。您在视图模型中不需要这些概念,因此应改用INotifyPropertyChanged

仅将视图模型作为传递到模型层的方式没有任何价值。所以不要这样做!您不应该仅仅因为认为应该而向代码添加层、结构或概念。简单性是您始终应该追求的东西。

因此,如果您可以实现具有INotifyPropertyChanged的模型层,则只需将其绑定到视图即可。

然而...在某些情况下,您可能无法在模型中实现INotifyPropertyChanged。例如,它可能是从Web服务生成的。在这种情况下,您将需要一个视图模型来执行传递功能,但还通过INotifyPropertyChanged添加更改通知。


我对于视图直接绑定模型感到犹豫不决,并且我看到了不同的意见。原始的Fowler没有直接联系。Gossman允许“在简单的例子中,视图可以直接绑定到模型”。Smith则强调:“视图类根本不知道模型类的存在”。虽然我很新手,但是我的直觉更喜欢清晰的分离,不允许视图-模型绑定。你有什么想法? - rice
虽然我同意你不应该仅仅为了增加层级而添加一个层,但我不愿意将ViewModel视为简单的传递。在许多情况下,它可能在表面上看起来像这样(例如编辑视图),但是ViewModel服务于视图,而Model应该服务于业务规则和持久性实现。 ViewModel通过INotifyPropertyChanged处理向视图的通知和通过IDataErrorInfo处理验证错误。域对象可以被Web服务消耗或通过它们传输(例如到Silverlight客户端)。视图特定的细节会妨碍这一过程。 - Steve Py

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