// ReSharper restore RedundantOverridenMember /// <summary> /// Suspends the change callbacks whenever a property has been called. This is very useful when /// there are expensive property change callbacks registered with a property that need to be /// temporarily disabled. /// </summary> /// <returns></returns> public IDisposable SuspendChangeCallbacks() { var token = new DisposableToken <ModelBase>(this, x => { lock (_lock) { if (_changeCallbacksSuspensionContext is null) { _changeCallbacksSuspensionContext = new SuspensionContext(); } _changeCallbacksSuspensionContext.Increment(); } }, x => { lock (_lock) { var suspensionContext = _changeCallbacksSuspensionContext; if (suspensionContext != null) { suspensionContext.Decrement(); if (suspensionContext.Counter == 0) { _changeCallbacksSuspensionContext = null; } } } // Note: don't invoke the "missed" callbacks }); return(token); }
/// <summary> /// Suspends the validation until the disposable token has been disposed. /// </summary> /// <returns></returns> public IDisposable SuspendValidations(bool validateOnResume = true) { var token = new DisposableToken <ModelBase>(this, x => { lock (_lock) { if (_validationSuspensionContext == null) { _validationSuspensionContext = new SuspensionContext(); } _validationSuspensionContext.Increment(); } }, x => { SuspensionContext suspensionContext; lock (_lock) { suspensionContext = _validationSuspensionContext; if (suspensionContext != null) { suspensionContext.Decrement(); if (suspensionContext.Counter == 0) { _validationSuspensionContext = null; } } } if (suspensionContext != null && suspensionContext.Counter == 0) { if (!validateOnResume) { // Only catch up what we missed var properties = suspensionContext.Properties; foreach (var property in properties) { ValidatePropertyUsingAnnotations(property); } } else { // We need to force validation on attributes again with this flag Validate(true, true); } } }); return(token); }
/// <summary> /// Suspends the change notifications until the disposed object has been released. /// </summary> /// <param name="raiseOnResume">if set to <c>true</c>, the notifications are invoked on resume.</param> /// <returns>A disposable object.</returns> public IDisposable SuspendChangeNotifications(bool raiseOnResume = true) { var token = new DisposableToken <ModelBase>(this, x => { lock (_lock) { if (_changeNotificationsSuspensionContext is null) { _changeNotificationsSuspensionContext = new SuspensionContext(); } _changeNotificationsSuspensionContext.Increment(); } }, x => { SuspensionContext suspensionContext; lock (_lock) { suspensionContext = _changeNotificationsSuspensionContext; if (suspensionContext != null) { suspensionContext.Decrement(); if (suspensionContext.Counter == 0) { _changeNotificationsSuspensionContext = null; } } } if (raiseOnResume) { if (suspensionContext != null && suspensionContext.Counter == 0) { var properties = suspensionContext.Properties; foreach (var property in properties) { RaisePropertyChanged(property); } } } }); return(token); }