1

I have an ObservableCollection and I want to know when a control is added or removed from it. I have searched online and tried all of these questions and other websites but these did not help me at all!

Implementing CollectionChanged

Fire an event when Collection Changed (add or remove)

Here is my current code:

public partial class PageView : UserControl
{
    public class PageViewCollection : ObservableCollection<PageViewPage>
    {
        public PageViewPage GetByName()
        {
            PageViewPage pgp = new PageViewPage();

            foreach (PageViewPage page in this)
            {
                if (page.Name == ID)
                {
                    pgp = page;
                }
            }

            return pgp;
        }
    }

    private PageViewCollection pages { get; set; }

    [Bindable(true)]
    [EditorBrowsable(EditorBrowsableState.Always)]
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
    [Browsable(true)]
    [Category("Behavior")]
    public PageViewCollection Pages
    {
        get { return pages; }
        set
        {
            if (pages != value)
            {
                pages = value; this.Invalidate();
                if (PagesChanged != null)
                {
                    PagesChanged(this, EventArgs.Empty);
                }
            }
        }
    }

    [Browsable(true)]
    public event EventHandler PagesChanged;
}

If I add a control, it still won't notify that the collection has changed. Any help is appreciated.

Community
  • 1
  • 1
  • 1
    did you try this: In `PageViewCollection` class add `CollectionChanged += new NotifyCollectionChangedEventHandler(PagesChanged);` – Chandan Rai Jan 29 '17 at 08:10

1 Answers1

0

You have it backwards. You are creating a PageViewCollection object that inherits from ObservableCollection. This can be done but I don't think this is what you are intending.

You need to make it like so

public ObservableCollection<PageView> PageViews { get; set; }

When you use PageViews.Add or PageView.Remove or .Clear etc. anything binding to PageViews will be notified automatically.

Remember this ONLY notifies objects of the items being added / removed / cleared from the collection and does NOT update the object binding to it if the PageViews collection changes to a new ObservableCollection.

In order to make sure binding to PageViews is always solid you should write it completely out using INotifyPropertyChanged or as a DependencyProperty.

public ObservableCollection<PageView> PageViews
{
     get { return pageViews; }
     set 
     {
        pageViews = value;
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(PageViews)));
     }
}

To help make sense of this ObservableCollection exposes the CollectionChanged event and when the collection is altered it is fired causing any binding to the collection to update.

It also exposes the PropertyChanged event but the only property that would fire is the Count property.

Any {Binding} expression in XAML will look for both of these events for binding so you don't need to do any extra work.

If you want to do this in code you can properly write a binding to the object which will wire things up the proper way or you can just cheat and listen to the CollectionChanged event yourself.

PageViews.CollectionChanged = (s, e) => { ... };
Michael Puckett II
  • 6,586
  • 5
  • 26
  • 46
  • It does not help because I want to use ObservableCollection as a class so I can add my own methods. – Landon Conway Jan 29 '17 at 16:08
  • Ok, well the same applies then. Keep the code your current way and use PageViewCollection.Add / Remove / Clear methods. If you're trying to listen for the changes programmatically and don't feel like writing a proper binding mechanism then just listen for the CollectionChanged event like I mentioned. PageViewCollection.CollectionChanged += ... – Michael Puckett II Jan 29 '17 at 21:06
  • 1
    It looks to me like you're listening for the PagesChanged event. The PagesChanged event will only fire if you assign to your property... Like ( Pages = new PageViewCollection() ) The way to listen to the collection of the pages changing it to listen to the CollectionChanged event. That will fire when a page is added / removed etc from the collection. – Michael Puckett II Jan 29 '17 at 21:09