DependencyProperty中的属性已更改

问题描述 投票:2回答:4

previous post中,我问如何将属性注册为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(单击按钮),则不会触发该事件。

有人知道为什么吗?

c# wpf dependency-properties
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的其他实现。有关更多信息,请参见herehere


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)
    {

    }

0
投票

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


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)
{
    ...
}
推荐问答
热门问答
最新问答