依赖属性的PropertyChangedCallback没有被调用 [英] Dependency Properties' PropertyChangedCallback not getting called
问题描述
如果具有自己的带有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 Rates(例如,使用this.Rates = new ObservableCollection<double>() { 1.0, 2.0 }
)时,将按预期方式调用用户控件的OnRatesChanged()方法.但是当我执行以下命令时,它不会被调用:
this.Rates[0] = (double)1;
this.Rates[1] = (double)2;
OnPropertyChanged("Rates");
我希望当我使用正确的属性名称引发PropertyChanged事件时,总是会调用用户控件中的相应回调.那是错的吗? 我找到了这个线程:始终获取依赖项属性的PropertyChangedCallback-Silverlight 一个> 涵盖了Silverlight,但是我认为在WPF中也是如此.
因此,后台的Framework检查绑定属性(在我的示例中为"Rates")是否已更改,并且仅在更改后,才调用关联的回调,对吗?因此,更改收藏夹中的元素没有任何效果,我总是必须更改整个收藏夹吗?
谢谢!
您的结论是正确的,仅当Rates
依赖项属性设置为新集合(或为null)时,才会调用OnRatesChanged
回调./p>
为了获得有关集合中更改的通知,您还必须注册一个 When using this user control, I bind an ObservableCollection called "Rates" to the RatesProperty. Rates and the related methods look like this: When I change the ObservableCollection Rates (e.g. with I expected that when I raise the PropertyChanged event with the correct property name, the corresponding callback in the user control is always called. Is that wrong?
I found this thread: Getting PropertyChangedCallback of a dependency property always - Silverlight
which covers silverlight but I think then that the same is true in WPF. So the Framework in the background checks if the bound property (in my example "Rates") changed and only if it changed, it calls the associated callback, correct? Thus changing the elements of my collection has no effect, I always have to change the complete collection? Thank you! Your conclusion is right, your In order to get notified about changes in the collection, you would also have to register a NotifyCollectionChangedEventHandler:
这篇关于依赖属性的PropertyChangedCallback没有被调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!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));
}
this.Rates = new ObservableCollection<double>() { 1.0, 2.0 }
) the OnRatesChanged() method of the user-control is called like expected. But when I execute the following, it is not called:this.Rates[0] = (double)1;
this.Rates[1] = (double)2;
OnPropertyChanged("Rates");
OnRatesChanged
callback will only be called when the Rates
dependency property is set to a new collection (or null).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();
}