我对这种方法的细节很感兴趣。 如何以及通过什么属性的价值变化进行跟踪?
答案 0 :(得分:4)
安德鲁史密斯有一个cool blog post关于它,我认为这对你有帮助。
我所看到的解决方案就是到达
PropertyDescriptor
并使用其AddValueChanged
方法提供EventHandler
在财产发生变化时收到通知。 有时,回复会提及/使用DependencyPropertyDescriptor
直接,但它是相同的东西,因为这只是一个派生 PropertyDescriptor提供有关的其他信息 它代表的底层DependencyProperty。你可以做到这一点 属性描述符在几个方面,但最常见的是得到它 从TypeDescriptor.GetProperties方法或使用 DependencyPropertyDescriptor.FromProperty。这种方法的问题在于它会根据你的对象它 将永远不会被GC收集。有很多 关于如何挂钩事件(特别是静态事件)的讨论可以 根你的对象,所以我不会在那里详细介绍。虽然确实如此 从本质上讲,在这种情况下你似乎并没有挂钩静态事件 你是。当您向属性描述符添加处理程序时,即 属性描述符将委托存储在由键控的哈希表中 你要挂钩的物品。代理/处理程序基本上是 指向对象上方法的指针(如果是静态则不指向对象) 方法)这意味着属性描述符有一个对你的引用 对象以及您正在观看其值的对象(从那以后) 是哈希表的关键)。属性描述符本身 静态缓存,因此哈希表保持不变 你的对象和你正在观看的对象也是如此。
答案 1 :(得分:1)
PropertyDescriptor
是一个抽象类,因此根据您手头的具体实现,可能有很多关于如何触发 value changed 事件的答案。但可能一个常见的情况是当 PropertyDescriptor
已经通过反射获得时,在这种情况下,我认为 ReflectPropertyDescriptor
的对象被返回。
查看该类的 reference source,您可以看到该事件仅在调用 SetValue()
方法时引发。据我了解,这意味着如果您只是这样做:
someObject.A = "value";
不会引发 ValueChanged
事件。
但是,如果您获得属性 ReflectPropertyDescriptor
的 A
并使用它来间接设置值,如下所示:
descriptor.SetValue(someObject, "value");
那会引发事件。
换个角度考虑,当设置属性值时,CLR 似乎无法在更基本的级别上实际引发事件。我假设这样的事情会产生通常不受欢迎的开销,因为每次在任何属性上设置一个值时,每个集合(实际上只是一个函数调用)都必须检查事件订阅者,即使没有事件订阅者。