1

I have a ListBox with its ItemSource bound to an ObservableCollection.

I have an attached behavior activated in this ListBox. This attached behavior hooks into the change event for the ItemsSource property. When this event is fired it checks if the new ItemsSource value is of type INotifyCollectionChanged and if so, it hooks into its CollectionChanged event as well.

But when this event is fired, I don't have access to the ListBox anymore, just to the ObservableCollection.

Is there an event in the ListBox that fires, when the content of its ItemsSource is changed? So that I have access to the ListBox?

Nostromo
  • 1,177
  • 10
  • 28

1 Answers1

2

So, there is no such event, However, we can use the Items property to get around that.

First of all, we will need to subscribe to the CollectionChanged event of the Items property:

((INotifyCollectionChanged)listBox.Items).CollectionChanged += Handler

Now we have access to the ItemCollection:

void Handler(object sender, NotifyCollectionChangedEventArgs e) 
{ 
   var items = (ItemCollection)sender; 
}

As an answer to this question suggests, there is no public accessor for the parent ItemsControl of the ItemCollection. However, this piece of reference source shows us that the framework has it in the form of this field and this convenient property. Now we just have to get reference to it. You can speed things up by using delegates (obviously you would cache them as static fields, below code is for demonstration purposes).

var getterMethodInfo = typeof(ItemCollection).GetProperty("ModelParent", BindingFlags.NonPublic | BindingFlags.Instance).GetGetMethod(true);
var getterDelegate = (Func<ItemCollection, DependencyObject>)Delegate.CreateDelegate(typeof(Func<ItemCollection, DependencyObject>), getterMethodInfo);

var listBox = (ListBox)getterDelegate(items);
TripleAccretion
  • 312
  • 3
  • 10
  • Thank you. For everyone trying that, be sure to hook into the `CollectionChanged` event of the `ListBox`s `ItemsCollection`, not into the `CollectionChanged` event of the `ObservableCollection` you bind the `ItemsSource` to. – Nostromo Oct 13 '19 at 06:26