为什么附加属性属性更改事件只触发一次?

我有一个绑定到对象列表的列表框。 对于每个列表项,我想要一个矩形,其填充颜色由绑定对象的一些属性确定。 所以我做了以下事情:

  1. 确保在我的对象上实现了INotifyPropertyChanged。
  2. 创建了一个类来公开我感兴趣的属性作为附加属性。
  3. 将对象的属性绑定到矩形的附加属性
  4. 创建了一个样式,该样式使用触发器根据附加属性设置矩形填充。

这是有效的,但只是第一次对象的属性发生变化。 之后,附加属性似乎在数据对象的属性更改时不会收到通知。 我已经仔细检查过,我的数据对象正在引发INotifyPropertyChanged事件。 可能是什么问题呢?

 

风格:

                    

附属物类:

 Public Class RecordAttachment Public Shared ReadOnly RecordStateProperty As DependencyProperty Public Shared ReadOnly IsDeletedProperty As DependencyProperty Shared Sub New() RecordStateProperty = DependencyProperty.RegisterAttached("RecordState", _ GetType(Model.RecordState), _ GetType(RecordAttachment), _ New PropertyMetadata(Model.RecordState.Unchanged, AddressOf RecordStatePropertyChanged)) IsDeletedProperty = DependencyProperty.RegisterAttached("IsDeleted", _ GetType(Boolean), _ GetType(RecordAttachment), _ New PropertyMetadata(AddressOf DeletedPropertyChanged)) End Sub Public Shared Sub SetRecordState(ByVal element As UIElement, ByVal state As Model.RecordState) element.SetValue(RecordStateProperty, state) End Sub Public Shared Function GetRecordState(ByVal element As UIElement) As Model.RecordState Return CType(element.GetValue(RecordStateProperty), Model.RecordState) End Function Public Shared Sub SetIsDeleted(ByVal element As UIElement, ByVal value As Boolean) element.SetValue(IsDeletedProperty, value) End Sub Public Shared Function GetIsDeleted(ByVal element As UIElement) As Boolean Return CType(element.GetValue(IsDeletedProperty), Boolean) End Function Public Shared Sub RecordStatePropertyChanged(ByVal sender As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs) If sender IsNot Nothing Then sender.SetValue(RecordStateProperty, e.NewValue) End If End Sub Public Shared Sub DeletedPropertyChanged(ByVal sender As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs) If sender IsNot Nothing Then sender.SetValue(IsDeletedProperty, e.NewValue) End If End Sub End Class 

有人建议我发布C#版本,所以这里是:

  public class RecordAttachment { public static readonly DependencyProperty RecordStateProperty; public static readonly DependencyProperty IsDeletedProperty; static RecordAttachment() { RecordStateProperty = DependencyProperty.RegisterAttached("RecordState", typeof(model.RecordState), typeof(RecordAttachment), new PropertyMetadata(model.RecordState.Unchanged, RecordStatePropertyChanged)); IsDeletedProperty = DependencyProperty.RegisterAttached("IsDeleted", typeof(bool), typeof(RecordAttachment), new PropertyMetadata(DeletedPropertyChanged)); } public static void SetRecordState(UIElement element, model.RecordState state) { element.SetValue(RecordStateProperty, state); } public static model.RecordState GetRecordState(UIElement element) { return (model.RecordState)element.GetValue(RecordStateProperty); } public static void SetIsDeleted(UIElement element, bool value) { element.SetValue(IsDeletedProperty, value); } public static bool GetIsDeleted(UIElement element) { return (bool)element.GetValue(IsDeletedProperty); } public static void RecordStatePropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) { if (sender != null) sender.SetValue(RecordStateProperty, e.NewValue); } public static void DeletedPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) { if (sender != null) sender.SetValue(IsDeletedProperty, e.NewValue); } } 

更新我通过使用数据触发器而不是使用附加属性和常规触发器解决了我需要更改矩形填充颜色的基本问题。 我仍然想知道为什么附加属性’propertychanged’事件只被触发一次。

我做了一些谷歌搜索,我遇到了这个链接 ,其中约什史密斯说’附加属性只能在元素上设置一次。’。 我环顾四周,找不到任何解释……

问题是由属性更改处理程序中的这些代码行引起的:

 sender.SetValue(RecordStateProperty, e.NewValue) 

 sender.SetValue(IsDeletedProperty, e.NewValue) 

通过调用SetValue,您将在目标上设置新的本地值。 设置本地值将替换先前可能已存在的任何数据绑定。

简而言之,您的属性更改处理程序会删除该属性的数据绑定。

由于您实际上正在删除绑定,因此当数据源发生更改时,您的属性将不再更改,因为它不再是该属性的数据源。

属性更改通知就是这样 – 它告诉您属性的值正在发生变化。 如果您不愿意,您不需要做任何响应,特别是,您不负责更改属性。 无论如何它会改变。

除了选择的答案,这也可以通过使用来解决

 Sender.SetCurrentValue(IsDeletedProperty, e.NewValue) 

这将在不更改源的情况下更改依赖项的值