2

I have an ItemsControl object that is binded to an ObservableCollection.

Here is my ItemsControl:

<ItemsControl x:Name="AvailableProjects" ItemsSource="{Binding ProjectsList}">
                    <ItemsControl.ItemsPanel>
                        <ItemsPanelTemplate>
                            <StackPanel Orientation="Vertical" />
                        </ItemsPanelTemplate>
                    </ItemsControl.ItemsPanel>
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <Grid>
                                <CheckBox x:Name="IsProjectSelected" IsChecked="{Binding IsProjectSelected}" />
                            </Grid>
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>
                </ItemsControl>

And here is my ObservableCollection:

public ObservableCollection<ProjectInfo> ProjectsList  { get; set; }

I would like that when the user presses the checkBox the "CollectionChanged" event of the observableCollection was fired but it's not working. I noticed that the checkbox item is handling the event and seems that the ObservableCollection doesn't notice. Someone can help me with this? Thanks in advance!

  • possible duplicate of [Notify ObservableCollection when Item changes](http://stackoverflow.com/questions/8490533/notify-observablecollection-when-item-changes) – ΩmegaMan Sep 11 '15 at 17:30

2 Answers2

7

ObservableCollection purpose are to notify the change of a collection, to notify the modification of an object you must implement INotifyPropertyChanged in the object contained in the collection.

SamTh3D3v
  • 9,854
  • 3
  • 31
  • 47
Mattia Magosso
  • 503
  • 2
  • 9
  • I implemented INotifyPropertyChanged in the ProjectInfo class but still doesn't work. – Ricardo Magalhães Sep 11 '15 at 16:57
  • public class ProjectInfo : INotifyPropertyChanged { private bool isProjectSelected; /// /// Is current project selected /// public bool IsProjectSelected { get { return this.isProjectSelected; } set { this.isProjectSelected = value; this.OnPropertyChanged(); } } – Ricardo Magalhães Sep 11 '15 at 17:02
  • Hello Mattia! First let me thank you for your help! What I mean was that I implemented the INotifyPropertyChanged in the bool property isProjectSelected of the class ProjectInfo (type of ObservableCollection) but still the event "CollectionChanged" of the ObservableCollection is not firing when a user check one of the checkbox items list – Ricardo Magalhães Sep 12 '15 at 07:46
  • Hi Ricardo, probably I wasn't clear before but what I meant is that you will be notified from a `CollectionChanged` event when a property of any item of the collection has changed. What you have to do is to attach to the `PropertyChanged` of every single item in the collection. – Mattia Magosso Sep 12 '15 at 11:05
  • 2
    Hi Mattia! You are right! Thank you so much. Just as a plus a found a good example in CodeProject: http://www.codeproject.com/Tips/694370/How-to-Listen-to-Property-Chang – Ricardo Magalhães Sep 12 '15 at 15:19
1

Final Solution (Thank you to Mattia Magosso and Vijaya Krishna Paruchuri for your help).

PS: I added a new event "ItemChanged" to this custom ObservableCollection that is fired everytime an item is updated

    using System;

    namespace HRGEnvironmentTool.Custom
    {
    using System.Collections;
    using System.Collections.ObjectModel;
    using System.Collections.Specialized;
    using System.ComponentModel;


    /// <summary>
    ///     This class adds the ability to refresh the list when any property of
    ///     the objects changes in the list which implements the INotifyPropertyChanged. 
    /// </summary>
    /// <typeparam name="T">
    public class ItemsChangeObservableCollection<T> : 
           ObservableCollection<T> where T : INotifyPropertyChanged
    {

        public delegate void ItemChangedEventHandler(object source, EventArgs args);

        /// <summary>
        /// Event fired when an item of the collection is updated
        /// </summary>
        public event ItemChangedEventHandler ItemChanged;

        protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
        {
            if (e.Action == NotifyCollectionChangedAction.Add)
            {
                RegisterPropertyChanged(e.NewItems);
            }
            else if (e.Action == NotifyCollectionChangedAction.Remove)
            {
                UnRegisterPropertyChanged(e.OldItems);
            }
            else if (e.Action == NotifyCollectionChangedAction.Replace)
            {
                UnRegisterPropertyChanged(e.OldItems);
                RegisterPropertyChanged(e.NewItems);
            }

            base.OnCollectionChanged(e);
        }

        protected override void ClearItems()
        {
            UnRegisterPropertyChanged(this);
            base.ClearItems();
        }

        private void RegisterPropertyChanged(IList items)
        {
            foreach (INotifyPropertyChanged item in items)
            {
                if (item != null)
                {
                    item.PropertyChanged += new PropertyChangedEventHandler(item_PropertyChanged);
                }
            }
        }

        private void UnRegisterPropertyChanged(IList items)
        {
            foreach (INotifyPropertyChanged item in items)
            {
                if (item != null)
                {
                    item.PropertyChanged -= new PropertyChangedEventHandler(item_PropertyChanged);
                }
            }
        }

        private void item_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            OnItemChange();
        }

        protected virtual void OnItemChange()
        {
            if (ItemChanged != null)
            {
                ItemChanged(this, EventArgs.Empty);
            }
        }
    }

}