2

上一篇文章中,我询问了如何将属性注册为 DependencyProperty。我得到了一个答案,它工作正常。

但现在我想在单击时向此 DependencyProperty 添加一些项目。这行不通。我注册 DependencyProperty 的代码是:

public static readonly DependencyProperty ChartEntriesProperty = DependencyProperty.Register(
        "ChartEntries", typeof(ObservableCollection<ChartEntry>), typeof(ChartView),
        new FrameworkPropertyMetadata(OnChartEntriesChanged));

    private static void OnChartEntriesChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {

    }

OnChartEntriesChanged-Event 在我将 XAML 绑定到我的 c# 代码时被调用。但是,如果我之后添加 ChartEntry(单击按钮),则不会触发该事件。

有谁知道为什么?

4

4 回答 4

5

将项目添加到ChartEntries集合时,实际上并没有更改该属性,因此不会调用 PropertyChangedCallback。为了获得有关集合更改的通知,您需要注册一个额外的CollectionChanged事件处理程序:

private static void OnChartEntriesChanged(
    DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
    var chartView = (ChartView)obj;
    var oldCollection = e.OldValue as INotifyCollectionChanged;
    var newCollection = e.NewValue as INotifyCollectionChanged;

    if (oldCollection != null)
    {
        oldCollection.CollectionChanged -= chartView.OnChartEntriesCollectionChanged;
    }

    if (newCollection != null)
    {
        newCollection.CollectionChanged += chartView.OnChartEntriesCollectionChanged;
    }
}

private void OnChartEntriesCollectionChanged(
    object sender, NotifyCollectionChangedEventArgs e)
{
    ...
}

ObservableCollection<ChartEntry>不使用属性类型也是有意义的,而是简单地ICollectionIEnumerable代替。这将允许INotifyCollectionChanged具体集合类型中的其他实现。有关更多信息,请参见此处此处

于 2013-10-24T06:50:39.937 回答
1

OnChartEntriesChanged当您设置ObservableCollection. 您将不得不收听如下更改的收藏:

    private static void OnChartEntriesChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        ((ObservableCollection<ChartView>)e.OldValue).CollectionChanged -= new System.Collections.Specialized.NotifyCollectionChangedEventHandler(ChartView_CollectionChanged);   
        ((ObservableCollection<ChartView>)e.NewValue).CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(ChartView_CollectionChanged);   
    }

    static void ChartView_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
    {

    }
于 2013-10-24T06:53:13.190 回答
0

抱歉,这不起作用,因为您已经检测到自己。DependencyProperty 更改的处理程序仅在属性值更改时才会触发,但在您的情况下不会触发,因为对象引用仍然相同。您必须在提供的集合的 CollectionChanged 事件处理程序上注册。(您可以在依赖属性的 propertychanged 处理程序中执行此操作)

于 2013-10-24T06:49:47.603 回答
0

Clemens的回答看起来不错,对我帮助很大。但是,在许多情况下,您希望在将整个集合替换为另一个集合时也调用 CollectionChanged 事件处理程序。为此,只需从 PropertyChanged 事件处理程序显式直接调用 CollectionChanged 事件处理程序。完整的代码如下所示。

private static void OnChartEntriesChanged(
    DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
    var chartView = (ChartView)obj;
    var oldCollection = e.OldValue as INotifyCollectionChanged;
    var newCollection = e.NewValue as INotifyCollectionChanged;

    if (oldCollection != null)
    {
        oldCollection.CollectionChanged -= chartView.OnChartEntriesCollectionChanged;
    }

    if (newCollection != null)
    {
        newCollection.CollectionChanged += chartView.OnChartEntriesCollectionChanged;
    }

    // The first parameter below can also be null
    chartView.OnChartEntriesCollectionChanged(newCollection, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}

private void OnChartEntriesCollectionChanged(
    object sender, NotifyCollectionChangedEventArgs e)
{
    ...
}
于 2019-10-21T11:35:26.273 回答