WPF MVVM 模型的 DependencyProperty 模拟 [英] DependencyProperty analogue for WPF MVVM Model

查看:49
本文介绍了WPF MVVM 模型的 DependencyProperty 模拟的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有我的 MVVM,模型由许多相关的类组成,但为了这个问题,我们将只关注四个.

I have my MVVM and the model consists of a number of related classes, but for the sake of this question we'll focus on just four.

GrandParentModel、ParentModel、ChildModel 和 Contact.

GrandParentModel, ParentModel, ChildModel and Contact.

这些都继承自 ModelBase,它有一个 INotifyPropertyChanged 的​​实现.

These all inherit from ModelBase which has an implementation of INotifyPropertyChanged on it.

所以三个模型中的每一个都有一个 Contact 属性.如果 Child 没有属性,它应该查找 Parent,如果 Parent 为空,它将查找 GrandParent.如果联系人在祖父母级别发生变化,我希望任何受抚养人,即任何子父母和他们的孩子也为他们的联系人引发 PropertyChanged 事件.

So each of the three models has a Contact property. If Child doesn't have a property it is supposed to look to Parent, and if Parent is blank it will look to GrandParent. If the contact changes at the grandparent level I'd like any dependants, ie any sub parents and their children to raise a PropertyChanged event for their Contact too.

我认为我要做的一切都会得到 DependencyProperty 系统的支持,但我不想使用它,因为这是我的模型、关注点分离等等.所以我正在整理一个迷你实现,这一切都很好.

I think everything I'm going to do will be supported by the DependencyProperty system, but I don't want to use that as this is my Model, separation of concerns and all that. So I'm putting together a mini implementation, which is all fine.

我的问题是以前有人走过这条路吗,我将来有什么需要担心的吗?我的蜘蛛侠感觉刺痛,我不知道为什么.

My question is has anyone been down this path before and is there anything I should be worried about in the future? My Spidey-Senses are tingling and I don't know why.

谢谢伊恩

这里的对象之间的关系是祖父母有任意数量的父母有任意数量的孩子.我当前的模型在每个模型上都有一个指向父对象的属性(在祖父母的情况下为 null),并且父/祖父母有一组子对象.

The relationship between the objects here is that a grandparent has any number of parents has any number of children. My current model has a property on each which points at the parent (null in the case of a grandparent) and a parent/grandparent has a collection of child objects.

推荐答案

我一直在走这条路,但它并不漂亮.基本上,您必须从您的 ChildModel 订阅 ParentModelPropertyChanged 事件.如果您的孩子可以更换父母,您必须小心.然后,当您从孩子的角度收到有关父更改的通知时,您必须在孩子上引发自己的 PropertyChanged 事件.它变得丑陋,因为您最终可能会挂起忘记清理的事件处理程序.

I've been down this path, and it's not pretty. Basically you have to subscribe to the PropertyChanged event of ParentModel from your ChildModel. You have to take care if your child can change parents. Then when you get notified of a change in the parent from the child's point of view, you have to raise your own PropertyChanged event on the child. It gets ugly because you can end up with hanging event handlers that you forgot to clean up.

更好的方法是创建您自己的模型特定的 DependencyProperty 模拟.基本上在您的 ChildModel 构造函数中,您声明"该属性 Contact 在为 null 时委托给对象 Parent 的属性 Contact.您可以使用一个小助手类来执行此操作,该类观察 ParentModel 对象上的 PropertyChanged 事件,并让它在适当的时候在子对象上执行 PropertyChanged 事件.还要注意 Parent 属性在孩子上发生变化.

A better method would be to create your own Model-specific analog to DependencyProperty. Basically in your constructor of ChildModel you "declare" that property Contact delegates to property Contact of object Parent when null. You do that using a little helper class that observes the PropertyChanged event on the ParentModel object and have it execute a PropertyChanged event on the child when appropriate. Also have it watch for the Parent property to change on the child.

您可以使用 MVVM Light 消息总线.让祖父母和父母在他们的 Contact 属性更改时都发送一条消息.让孩子聆听这些信息.当它收到一条消息时,然后检查它是否与它自己的父或祖父匹配,并在必要时引发 PropertyChanged 事件.这比上述任何一种方法都要好,因为您不必跟踪您的父母或祖父母何时发生变化.你不太可能有错误.它还使用弱引用,因此它不会像事件处理程序那样保留对象.

You could use the MVVM Light message bus. Have the grandparent and parent all send a message when their Contact property changes. Have the child listen for those messages. When it gets a message, then check to see if it matches its own parent or grandparent, and raise a PropertyChanged event if necessary. This is better than either method above because you don't have to keep track of when your parent or grandparent changes. You're less likely to have bugs. It also uses weak references, so it won't hold on to objects the way event handlers do.

现在我一直在做的是摆脱让我的模型对象实现 INotifyPropertyChanged.我在模型和视图模型之间引入了一个 Presenter 层.Presenter 实际上是用小的 ViewModel小部件"(例如,一个小部件可能是一个 ChangeValue 小部件)构建了一个 ViewModel.我有一个规则引擎,它告诉 Presenter 如何从给定模型的小部件组成一个 ViewModel.Presenter 处理所有用户输入(基本上是针对模型执行 lambda),但由于它知道用户操作刚刚发生,因此它知道模型中的某些内容可能已更改.Model 操作完成后,它将所有数据从 Model 复制到 ViewModel.ViewModel 检查传入的数据并在字段实际更改时引发 PropertyChanged 事件.显然,这是最复杂的方法,但它为您提供了一个非常干净的模型,并且 ViewModel 和 Presenter 都不包含任何模型(域/业务)逻辑.

Now what I've been doing is getting away from having my model objects implement INotifyPropertyChanged. I introduced a Presenter layer between my Model and my ViewModel. The Presenter actually constructs a ViewModel out of small ViewModel "widgets" (one widget might be a ChangeValue<T> widget, for instance). I have a rules engine that tells the Presenter how to compose a ViewModel out of widgets for a given Model. The Presenter handles all user input (basically executing a lambda against the Model), but since it knows that a user action just took place, it knows that something in the Model might have changed. After the Model action is complete, it copies all of the data from the Model to the ViewModel. The ViewModel inspects the incoming data and raises a PropertyChanged event if the field actually changed. Obviously that's the most compliated way of doing it, but it gives you a really clean Model and neither the ViewModel nor the Presenter contains any Model (domain/business) logic.

这篇关于WPF MVVM 模型的 DependencyProperty 模拟的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆