PropertyDescriptor.AddValueChanged如何工作?

时间:2012-12-10 08:26:01

标签: c# .net

我对这种方法的细节很感兴趣。 如何以及通过什么属性的价值变化进行跟踪?

2 个答案:

答案 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 事件。

但是,如果您获得属性 ReflectPropertyDescriptorA 并使用它来间接设置值,如下所示:

descriptor.SetValue(someObject, "value");

那会引发事件。

换个角度考虑,当设置属性值时,CLR 似乎无法在更基本的级别上实际引发事件。我假设这样的事情会产生通常不受欢迎的开销,因为每次在任何属性上设置一个值时,每个集合(实际上只是一个函数调用)都必须检查事件订阅者,即使没有事件订阅者。