首页 文章

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

提问于
浏览
5

我是WPF / MVVM的新手,我发现的例子似乎并没有涵盖我所面临的问题 .

我有一个用于管理相当复杂的业务配置对象的屏幕 . 在MVVM中,我认为这意味着我应该拥有以下内容:

  • XAML视图,逻辑接近于零

  • 具有屏幕逻辑的ViewModel类

  • 我常用的业务类充当了Model的角色,拥有所有业务逻辑

在我的情况下,有业务规则说我的业务类fieldA的更改可能有各种副作用,例如更改fieldB的值,或填充整个子对象列表 .

我可能是错的,但我认为我应该将这些规则封装在业务类中,因为这些规则实际上并不是关于屏幕的实体 .

当然,这些副作用需要立即回到屏幕上 .

因此,从用户的角度来看,他可能会编辑fieldA,并在View上看到fieldB更新 .

我理解如何从View到ViewModel进行数据绑定 .

但就我而言,似乎我需要两层数据绑定:一个在View和ViewModel之间,另一个在ViewModel和Model之间 .

鉴于我有两次基本相同的问题,我认为应该适用一种解决方案 . 所以我将我的Model类变成了DependencyObject,并将其属性设置为DependencyProperties .

以fieldA为例,它将出现在所有三个层中:

  • 作为可视组件数据绑定到ViewModel.FieldA,例如text = "{Binding FieldA, Mode=TwoWay}"

  • ViewModel作为DependencyProperty绑定"upward"到视图,"downward"绑定到模型

  • Model作为DependencyProperty

我不想通过跳过第2部分将我的View XAML直接耦合到业务对象,这对我来说似乎不是一个干净的模式应用程序 . 也许这是错误的 .

我本质上似乎需要在我的ViewModel中使用“传递DependencyProperty” .

我的问题:

  • 这是正确的一般方法还是我认为这一切都错了?

  • 有没有使用这种传递方法的例子?

  • 有人能给出一个代码示例,说明在ViewModel和Model FieldA DependencyProperties之间创建传递绑定的正确方法吗?

3 回答

  • 0

    我自己也在努力解决这个问题,而且我认为这对于MVVM来说是一个非常普遍的障碍 . 我的答案是避免使用 DependencyObjectINotifyPropertyChanged 污染域名,因为它在某种程度上否定了使用ViewModel的有效性 .

    ViewModel的目标是以与特定视图相关的方式公开模型 . 当VM基本上需要公开整个域对象时,它会变得混乱 . 我将这些视为"Editor"视图模型 . 这些是从域对象传递属性最诱人的 . 在这些情况下,我给VM一个域对象(组合)的引用,并通过getter和setter . 如果UI需要刷新或显示验证错误,ViewModel采用 INotifyPropertyChangedIDataErrorInfo 而不是 DependencyProperty 来通知UI . 如果域引发验证错误,则VM捕获它并将其准备到视图的数据错误信息详细信息中 .

  • 0

    我同意Steve的意见,你应该避免在你的模型/域类中使用 DependencyObjectDependencyProperty ,并且视图模型类应该采用 INotifyPropertyChangedIDataErrorInfo 来进行绑定 .

    我想在你的视图模型类中添加它,我会避免使用 DependencyProperty ,除了你需要在xaml逻辑中使用的属性,例如 DataTrigger .

    为了处理在模型层类中触发的更改,我还可以在视图模型类中引用模型/域对象,并像Steve提到的那样将getter和setter传递给模型/域类 . 我想补充一点,模型/域类需要引发视图模型类需要订阅的事件,以便可以根据您的视图模型类中的更改调用一个或多个属性的 OnPropertyChanged() 商业逻辑 .

  • 1

    首先,我不建议对视图模型或模型使用依赖项属性(DP) . DP是在设计时考虑了UI概念的属性,例如优先规则,支持,默认值等 . 您在视图模型中不需要这些概念,因此您应该使用 INotifyPropertyChanged 而不是 .

    拥有一个视图模型,它只是模型层的传递 adds no value at all . 所以不要这样做!您不应该仅仅因为您认为应该将代码,结构或概念添加到代码中 . 简单是你应该一直努力的事情 .

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

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

相关问题