我有一个FreezableCollection,我想监视子属性的更改。以下是代码的一小部分:
public class FieldHeading : DependencyObject
{
public static readonly DependencyProperty LayoutProperty = DependencyProperty.Register("Layout", typeof(FieldHeadingLayout), typeof(FieldHeading),
new FrameworkPropertyMetadata(FieldHeadingLayout.Above,
FrameworkPropertyMetadataOptions.AffectsRender |
FrameworkPropertyMetadataOptions.AffectsMeasure |
FrameworkPropertyMetadataOptions.AffectsParentMeasure));
public FieldHeadingLayout Layout
{
get { return (FieldHeadingLayout) GetValue(LayoutProperty); }
set { SetValue(LayoutProperty, value); }
}
}
public class FieldPanel : FrameworkElement
{
private static readonly DependencyProperty FieldHeadingProperty = DependencyProperty.Register("FieldHeading", typeof(FreezableCollection<FieldHeading>), typeof(FieldPanel),
new FrameworkPropertyMetadata(null,
FrameworkPropertyMetadataOptions.AffectsMeasure |
FrameworkPropertyMetadataOptions.AffectsParentMeasure |
FrameworkPropertyMetadataOptions.AffectsRender, HeadingChanged));
private static void HeadingChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
Debug.WriteLine("Hello");
}
public FreezableCollection<FieldHeading> FieldHeadings
{
get
{ return (FreezableCollection<FieldHeading>) GetValue(FieldHeadingProperty); }
set { SetValue(FieldHeadingProperty, value);}
}
public FieldPanel()
{
AddVisual(_contentVisual = new DrawingVisual());
FieldHeadings = new FreezableCollection<FieldHeading>();
}
}
然后我们为其中一个FieldHeadings为Layout分配一个新值,不生成任何更改通知。显然我错过了一些重要的东西。从未调用HeadingChanged。
关于FreezableCollection的MSDN帮助,可在此处找到:FreezableCollection,声明:
事件已更改...在Freezable或其包含的对象被修改时发生。 (继承自Freezable。)
提前感谢您的帮助。
~Cameron
答案 0 :(得分:3)
更改通知处理程序仅在属性值更改时通知您,因此在这种情况下,如果freezable集合更改为新集合。在您的属性更改处理程序中,您需要订阅CollectionChanged
事件,在这种情况下,您需要在新项目上订阅PropertyChanged
事件。现在,最后,您将拥有一个事件,该事件将允许您对属于作为依赖项属性的可冻结集合的项的属性的更改做出反应。请记得取消订阅旧收藏品和旧物品的活动。
答案 1 :(得分:0)
问题是您只订阅了FieldHeadings
属性更改,这意味着只有在有人分配了集合本身的新实例时才会收到通知,例如, FeildHedings
属性设置器。
为了在Layout
属性更改时接收通知,您必须在FieldHeading
的每个单独实例上订阅它。
答案 2 :(得分:0)
实际上,您可以做您正在尝试做的事情。这正是FreezableCollection<T>
存在的原因!您需要做的就是将FieldHeading
更改为从Freezable
而不是DependencyObject
派生,对集合中项目的更改将提供相同的更改通知,就像整个项目已被替换一样。“ / p>
这是一个非常有用且鲜为人知的WPF功能。
这些可冻结的集合类会在项目添加到集合或从集合中删除时触发更改通知,当然,也可以在集合中任何项目的依赖项属性发生更改时触发更改通知。这是一个非常强大的机制。