【问题标题】:How to handle value change of dependency property?如何处理依赖属性的值变化?
【发布时间】:2014-02-06 10:23:22
【问题描述】:

我在 2 个属性之间使用数据绑定(绑定目标是依赖属性)。如果我改变绑定源的值,绑定目标也会改变(依赖属性的值)。我的问题是:如何处理依赖属性的值变化?

编辑:这是我注册依赖属性的方式:

public static DependencyProperty ItemsProperty = DependencyProperty.Register(
    ItemsPropertyName,
    typeof(List<ModelItem>),
    typeof(CentralPanel),
    new UIPropertyMetadata(null, OnItemsChanged));

所以当我在 OnItemsChanged 中设置断点时,该方法只运行一次,即第一次设置 binging source 的值。然后,当我改变绑定源的值时,绑定目标的值也改变了,但是 OnItemsChanged 没有触发,为什么?

【问题讨论】:

  • 当您说我更改绑定源的值时,您会更改整个列表或列表中的项目?
  • @dkozl:我更改了整个列表。有什么区别吗?
  • OnItemsChanged 仅在您将其设置为 List&lt;ModelItem&gt; 的不同实例时才会触发。如果它与您在列表中添加或删除项目的列表相同,则不会触发
  • @dkozl:我实际上是在清除列表并添加新元素。我会尝试制作 List... 的新实例
  • @dkozl:不幸的是它没有任何区别。

标签: c# wpf data-binding


【解决方案1】:

我其实是在清理列表并添加新元素

OnItemsChanged 仅在您将其设置为 List&lt;ModelItem&gt; 的不同实例时才会触发。如果它与您在列表中添加或删除项目的列表相同,则不会触发。

如果您希望您的列表在添加/删除项目时通知 UI 更改,它必须实现 INotifyCollectionChanged 接口,或者您可以使用现成的实现 ObservableCollection&lt;T&gt; 而不是 List&lt;T&gt;

如果您想在代码中捕获对集合的更改,您可以订阅 CollectionChanged 事件

在添加、删除、更改、移动项目或刷新整个列表时发生。

你可以在OnItemsChanged回调中做到这一点:

private void OnItemsChanged(DependencyPropertyChangedEventArgs e)
{
   var oldList = e.OldValue as ObservableCollection<ModelItem>;
   if (oldList != null) oldList.CollectionChanged -= MyCollectionChangedCallback;
   var newList = e.NewValue as ObservableCollection<ModelItem>;
   if (newList != null) newList.CollectionChanged += MyCollectionChangedCallback;
}

【讨论】:

  • 如何订阅 CollectionChanged 事件?即使是现在,当对象的新实例被设置为一个值并且我将绑定源和目标更改为 ObservableCollection 而不是 List 时,我捕获更改的标准方法(OnItemChanged 中的断点)方法也不起作用。
  • 当您使用ObservableCollection 时,您只使用一个实例,它会在添加/删除项目时通知 UI。因此,当您执行 var myList = new ObservableCollection&lt;ModelItem&gt;(); myList.CollectionChanged += MyCollectionChangedCallback; 时,每次添加/删除集合中的项目时,它都会调用 MyCollectionChangedCallback
  • 好的,我明白了。但请记住,设置 myList 的值仅在绑定源端完成。所以我可以在那里设置这个回调,但它没有用。那么我需要在绑定目标站点上创建这个回调吗?
  • 您可以在OnItemsChanged 中进行操作。在事件中使用e.NewValue,如果您也取消订阅e.OldValue(如果已分配)会很好
  • 让我更仔细地研究一下。似乎当 Items 属性“因为它被其他线程使用而无法访问”时触发此回调......
【解决方案2】:

每个网格视图都有一组在网格视图的 .aspx 定义中定义的事件函数,它们在页面的 aspx.cs 后面的代码中被信任。

EventArgs 事件的 e 参数包含 OldNew 的定义 某个属性的值:e.NewValues["PropertyName"]。此属性可帮助您处理依赖属性的更改值。

问候, 安多拉

【讨论】:

  • 是的,没错。但问题是,我可以检查 e 值的 OnItemsChanged 只运行一次。所以它向我显示 e.NewValue 作为一个值,而 e.OldValue 作为一个空值。我敢肯定,下次运行时,它将覆盖 OldValue,但问题是,该事件只运行一次 :)
  • 尝试使用以下甚至 OnItemsSourceChangedpublic static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register("ItemsSource", typeof(IEnumerable), typeof(ItemsControl), new FrameworkPropertyMetadata((IEnumerable)null, new PropertyChangedCallback(OnItemsSourceChanged))); private static void **OnItemsSourceChanged**(DependencyObject d, DependencyPropertyChangedEventArgs e) { e.Olde.New }跨度>
猜你喜欢
  • 2011-06-13
  • 1970-01-01
  • 2012-03-16
  • 1970-01-01
  • 1970-01-01
  • 2014-08-14
  • 1970-01-01
  • 2020-05-27
  • 1970-01-01
相关资源
最近更新 更多