title: How to detect changes in children from parent object in WPF?
body: <p>We have a WPF application, let’s say I have a Department object, in it I have an ObservableCollection of Courses, inside each Course I have an ObservableCollection of Teachers, and inside each Teacher I have an ObservableCollection of Student:</p>
  
  <p>Department.cs
  ---- ObservableCollection Courses</p>
  
  <p>Course.cs
  ---- ObservableCollection Teachers</p>
  
  <p>Teacher.cs
  ---- ObservableCollection Students</p>
  
  <p>Student.cs
  ---- Name, Age, etc</p>
  
  <p>These 4 classes all implemented INotifyPropertyChanged, they are working fine by themselves, what I want to achieve is whenever anything inside the Department object graph is changed, whether it was a student’s age get changed, or a new course added or a teacher removed, anything at all, I want to know about it, ideally via an event like DepartmentChanged (and ideally this only raise once), so I can call some other long running action.</p>
  
  <p>I have a hard time coming up with a clean way to do it. I understand that INotifyPropertyChanged only track property change of a class and ObservationCollection has no idea if one of its items has changed something. </p>
  
  <p>So far I tried nested loop like (pseudo code):</p>
  
  <pre><code>foreach (var course in d.Courses){
      foreach (var teacher in course.Teachers){
          foreach (var student in teacher.Students){
              ((INotifyPropertyChanged)student).PropertyChanged += ...
          }
          teacher.Students.CollectionChanged += ...
      }
  }
  </code></pre>
  
  <p>But as can imagine, this created lots of PropertyChanged events since every property subscribe to that, and the action I wanted to do in Department ended up being executed many many times, which is bad.</p>
  
  <p>I then tried using a timer (each of our class has an IsDirty() to determine if the object has changed) with interval set to 500:</p>
  
  <pre><code>if(department != null &amp;&amp; department.IsDirty()){
      //call some long running Action here
  }
  </code></pre>
  
  <p>While this seems to work, somehow I feel this approach is wrong, I'd really like to avoid timer if possible, I would love to hear other suggestions and ideas!</p>
  
  <p>Thanks,</p>