Search code examples
c#wpfdependency-propertiesitemscontrolpropertychangelistener

How to Override PropertyChangedCallback of a predefined Dependency Property ItemsSource in a WPF ItemsControl


How to Override PropertyChangedCallback of a predefined Dependency Property ItemsSource in a WPF ItemsControl.

I developed a WPF Custom Control inherited from ItemsControl. In that I used the predefined Dependency Property ItemsSource. In that I need to monitor and check data once the Collection gets updated.

I searched a lot in google, but I can't able to find any related solution to fulfill my requirement.

https://msdn.microsoft.com/en-us/library/system.windows.controls.itemscontrol.itemssource(v=vs.110).aspx

Kindly assist me, whats the method name to Override ?...


Solution

  • Call OverrideMetadata in a static constructor of your derived ItemsSource class:

    public class MyItemsControl : ItemsControl
    {
        static MyItemsControl()
        {
            ItemsSourceProperty.OverrideMetadata(
                typeof(MyItemsControl),
                new FrameworkPropertyMetadata(OnItemsSourcePropertyChanged));
        }
    
        private static void OnItemsSourcePropertyChanged(
            DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            ((MyItemsControl)obj).OnItemsSourcePropertyChanged(e);
        }
    
        private void OnItemsSourcePropertyChanged(DependencyPropertyChangedEventArgs e)
        {
            var oldCollectionChanged = e.OldValue as INotifyCollectionChanged;
            var newCollectionChanged = e.NewValue as INotifyCollectionChanged;
    
            if (oldCollectionChanged != null)
            {
                oldCollectionChanged.CollectionChanged -= OnItemsSourceCollectionChanged;
            }
    
            if (newCollectionChanged != null)
            {
                newCollectionChanged.CollectionChanged += OnItemsSourceCollectionChanged;
                // in addition to adding a CollectionChanged handler
                // any already existing collection elements should be processed here
            }
        }
    
        private void OnItemsSourceCollectionChanged(
            object sender, NotifyCollectionChangedEventArgs e)
        {
            // handle collection changes here
        }
    }