Index: Ringtoets/Piping/src/Ringtoets.Piping.Forms/Views/PipingCalculationsView.cs =================================================================== diff -u -r3dc8c84f97530f446f2a53d231e8683e105f58e6 -r13919719112d513d5782320d8c0829c69b5e8d9e --- Ringtoets/Piping/src/Ringtoets.Piping.Forms/Views/PipingCalculationsView.cs (.../PipingCalculationsView.cs) (revision 3dc8c84f97530f446f2a53d231e8683e105f58e6) +++ Ringtoets/Piping/src/Ringtoets.Piping.Forms/Views/PipingCalculationsView.cs (.../PipingCalculationsView.cs) (revision 13919719112d513d5782320d8c0829c69b5e8d9e) @@ -45,7 +45,7 @@ private PipingCalculationGroup pipingCalculationGroup; private DataGridViewComboBoxColumn soilProfileColumn; private DataGridViewComboBoxColumn hydraulicBoundaryLocationColumn; - private readonly DynamicObserver pipingCalculationGroupObserver; + private readonly RecursiveObserver pipingCalculationGroupObserver; /// /// Creates a new instance of the class. @@ -55,7 +55,7 @@ InitializeComponent(); InitializeDataGridView(); - pipingCalculationGroupObserver = new DynamicObserver(UpdateDataGridViewDataSource); + pipingCalculationGroupObserver = new RecursiveObserver(UpdateDataGridViewDataSource, pg => pg.Children.OfType()); } /// @@ -228,12 +228,84 @@ #region Nested types - private class DynamicObserver : IObserver + private class RecursiveObserver : IObserver where T : IObservable { + private T observable; private readonly Action updateObserverAction; + private readonly Func> getChildObservables; + private readonly IList observedObjects = new List(); + + public RecursiveObserver(Action updateObserverAction, Func> getChildObservables) + { + this.updateObserverAction = updateObserverAction; + this.getChildObservables = getChildObservables; + } + + public T Observable + { + get + { + return observable; + } + set + { + observable = value; + + UpdateObservedObjects(); + } + } + + public void UpdateObserver() + { + updateObserverAction(); + + UpdateObservedObjects(); + } + + private void UpdateObservedObjects() + { + // Detach from the currently attached observable items + foreach (var observedObject in observedObjects) + { + observedObject.Detach(this); + } + + // Clear the list + observedObjects.Clear(); + + // If relevant, start observing objects again + if (observable != null) + { + foreach (var objectToObserve in GetObservablesRecursive(observable)) + { + objectToObserve.Attach(this); + observedObjects.Add(objectToObserve); + } + } + } + + private IEnumerable GetObservablesRecursive(T parentObservable) + { + var observables = new List + { + parentObservable + }; + + foreach (var childObservable in getChildObservables(parentObservable)) + { + observables.AddRange(GetObservablesRecursive(childObservable)); + } + + return observables; + } + } + + private class Observer : IObserver + { + private readonly Action updateObserverAction; private IObservable observable; - public DynamicObserver(Action updateObserverAction) + public Observer(Action updateObserverAction) { this.updateObserverAction = updateObserverAction; }