wpf – 未调用依赖属性的PropertyChangedCallback

如果拥有一个带有DependencyProperty的自己的用户控件和相应的回调方法,如下所示:
public partial class PieChart : UserControl
{
    public static readonly DependencyProperty RatesProperty = DependencyProperty.Register("Rates",typeof(ObservableCollection<double>),typeof(PieChart),new PropertyMetadata(new ObservableCollection<double>() { 1.0,1.0 },new PropertyChangedCallback(OnRatesChanged)));

[...]

    public static void OnRatesChanged(DependencyObject d,DependencyPropertyChangedEventArgs e)
    {
        ((PieChart)d).drawChart();
    }

使用此用户控件时,我将名为“Rates”的ObservableCollection绑定到RatesProperty.费率和相关方法如下所示:

private ObservableCollection<double> rates;
public ObservableCollection<double> Rates
{
    get { return this.rates; }
    set
    {
        if (this.rates != value)
        {
            this.rates = value;
            OnPropertyChanged("Rates");
        }
    }
}

public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
    if (PropertyChanged != null)
        PropertyChanged(this,new PropertyChangedEventArgs(propertyName));
}

当我更改ObservableCollection Rate(例如,使用this.Rates = new ObservableCollection< double>(){1.0,2.0})时,将调用用户控件的OnRatesChanged()方法,如预期.但是当我执行以下操作时,它不会被调用

this.Rates[0] = (double)1;
this.Rates[1] = (double)2;
OnPropertyChanged("Rates");

我期望当我使用正确的属性名称引发PropertyChanged事件时,始终会调用用户控件中的相应回调.那是错的吗?
我找到了这个帖子:Getting PropertyChangedCallback of a dependency property always – Silverlight
它涵盖了silverlight,但我认为在WPF中也是如此.

所以后台的框架检查绑定属性(在我的示例中为“Rates”)是否发生了变化,只有当它发生变化时才调用相关的回调,对吗?因此改变我的收藏元素没有任何效果,我总是要改变完整的收藏?

谢谢!

您的结论是正确的,只有在将rates依赖项属性设置为新集合(或null)时,才会调用OnRatesChanged回调.

为了获得有关集合更改的通知,您还必须注册NotifyCollectionChangedEventHandler

private static void OnRatesChanged(
    DependencyObject d,DependencyPropertyChangedEventArgs e)
{
    var pieChart = (PieChart)d;
    var oldRates = e.OldValue as INotifyCollectionChanged;
    var newRates = e.NewValue as INotifyCollectionChanged;

    if (oldRates != null)
    {
        oldRates.CollectionChanged -= pieChart.OnRatesCollectionChanged;
    }

    if (newRates != null)
    {
        newRates.CollectionChanged += pieChart.OnRatesCollectionChanged;
    }

    pieChart.drawChart();
}

private void OnRatesCollectionChanged(
    object sender,NotifyCollectionChangedEventArgs e)
{
    switch (e.Action)
    {
        ...
    }

    drawChart();
}

相关文章

适配器模式将一个类的接口转换成客户期望的另一个接口,使得原本接口不兼容的类可以相互合作。
策略模式定义了一系列算法族,并封装在类中,它们之间可以互相替换,此模式让算法的变化独立于使用算法...
设计模式讲的是如何编写可扩展、可维护、可读的高质量代码,它是针对软件开发中经常遇到的一些设计问题...
模板方法模式在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中,使得子类可以在不改变算法结...
迭代器模式提供了一种方法,用于遍历集合对象中的元素,而又不暴露其内部的细节。
外观模式又叫门面模式,它提供了一个统一的(高层)接口,用来访问子系统中的一群接口,使得子系统更容...