In a previous post I asked how to register a property as DependencyProperty. I got an answer and it works fine.
But now I want to add some Items to this DependencyP
Sorry but this won't work as you've detected yourself. The DependencyProperty changed handler does fire only, if the value of the property changes, but in your case it doesn't, as the object reference is still the same. You have to register on the CollectionChanged eventhandler of the provided collection. (this you can do in the propertychanged handler from the dependencyproperty)
When you add an item to the ChartEntries
collection, you do not actually change that property, so the PropertyChangedCallback isn't called. In order to get notified about changes in the collection, you need to register an additional CollectionChanged
event handler:
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)
{
...
}
It would also make sense not to use ObservableCollection<ChartEntry>
for the property type, but simply ICollection
or IEnumerable
instead. This would allow for other implementations of INotifyCollectionChanged
in the concrete collection type. See here and here for more information.
The answer from Clemens looks good and helped me a lot. However, in many cases you will want your CollectionChanged event handler to get called also when the entire collection is replaced with another collection. To do this, simply call the CollectionChanged event handler explicitly and directly from the PropertyChanged event handler. The full code would look as follows.
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)
{
...
}
OnChartEntriesChanged
callback will be called when you will set the new instance of the ObservableCollection
. You will have to listen to collection changed as below:
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)
{
}