protected virtual void OnChanged(IBindable <T> changedBinding) { if (_isUpdating) { return; } var wasSourceDisposed = (bool?)null; if (changedBinding == Target && (Mode & BindingMode.FromTarget) == 0) { return; } if (changedBinding == Source && (Mode & BindingMode.IntoTarget) == 0) { return; } _isUpdating = true; var isTarget = changedBinding.Equals(Target); var gettingFrom = isTarget ? "target" : "source"; var puttingIn = !isTarget ? "target" : "source"; var valueTarget = isTarget ? Source : Target; T value; try { value = changedBinding.Value; } catch (Exception ex) { if (ex is ObjectDisposedException || ex.InnerException is ObjectDisposedException) { Debug.WriteLine($"In binding ({BindingString}), when the {gettingFrom} changed, tried to get the value but the object was disposed."); wasSourceDisposed = changedBinding != Target; //!!!! WARNING WARNING WARNING !!!! CODER DISCRETION IS ADVISED: goto skipUpdate; } else { throw; } } try { valueTarget.Value = value; } catch (Exception ex) { if (ex is ObjectDisposedException || ex.InnerException is ObjectDisposedException) { Debug.WriteLine($"In binding ({BindingString}), when the {gettingFrom} changed, tried to update the {puttingIn}'s value, but the object was disposed."); wasSourceDisposed = changedBinding != Target; } else { throw; } } skipUpdate: _isUpdating = false; switch (wasSourceDisposed) { case true: Debug.WriteLine($"In binding ({BindingString}), the source (rightmost) was disposed, so the binding will be scrapped."); Dispose(); break; case false: Debug.WriteLine($"In binding ({BindingString}), the target (leftmost) was disposed, so the binding will be scrapped."); Dispose(); break; case null: //provided for emphasis break; } }