/// <summary> /// Unsubscribe all subscription. /// </summary> public void Dispose() { if (IsDisposed) { return; } var node = _root; _root = _last = null; _mode = (ReactivePropertyMode)IsDisposedFlagNumber; while (node != null) { node.OnCompleted(); node = node.Next; } ValidationTrigger.Dispose(); SourceDisposable.Dispose(); ValidateNotifyErrorSubscription.Dispose(); if (ErrorsTrigger.IsValueCreated) { ErrorsTrigger.Value.OnCompleted(); ErrorsTrigger.Value.Dispose(); } }
private void SetValue(T value) { LatestValue = value; ValidationTrigger.OnNext(value); Source.OnNext(value); RaiseEventScheduler.Schedule(() => PropertyChanged?.Invoke(this, SingletonPropertyChangedEventArgs.Value)); }
/// <summary>Helper for setting <see cref="ValidationTriggerProperty"/> on <paramref name="element"/>.</summary> /// <param name="element"><see cref="UIElement"/> to set <see cref="ValidationTriggerProperty"/> on.</param> /// <param name="value">ValidationTrigger property value.</param> public static void SetValidationTrigger(this UIElement element, ValidationTrigger value) { if (element is null) { throw new ArgumentNullException(nameof(element)); } element.SetValue(ValidationTriggerProperty, value); }
private void SetValue(T value) { LatestValue = value; if (!IsDisposed) { ValidationTrigger.OnNext(value); OnNextAndRaiseValueChanged(ref value); } }
internal ReactiveProperty( IObservable <T> source, IScheduler raiseEventScheduler, T initialValue = default(T), ReactivePropertyMode mode = ReactivePropertyMode.DistinctUntilChanged | ReactivePropertyMode.RaiseLatestValueOnSubscribe) { this.LatestValue = initialValue; this.RaiseEventScheduler = raiseEventScheduler; // create source var merge = source.Merge(AnotherTrigger); if (mode.HasFlag(ReactivePropertyMode.DistinctUntilChanged)) { merge = merge.DistinctUntilChanged(); } merge = merge.Do(x => { // setvalue immediately if (!IsValueChanged) { IsValueChanged = true; } LatestValue = x; }); // publish observable var connectable = (mode.HasFlag(ReactivePropertyMode.RaiseLatestValueOnSubscribe)) ? merge.Publish(initialValue) : merge.Publish(); this.Source = connectable.AsObservable(); this.ValidationTrigger = mode.HasFlag(ReactivePropertyMode.RaiseLatestValueOnSubscribe) ? (ISubject <T>) new BehaviorSubject <T>(initialValue) : (ISubject <T>) new Subject <T>(); connectable.Subscribe(x => ValidationTrigger.OnNext(x)); // raise notification this.RaiseSubscription = connectable .ObserveOn(raiseEventScheduler) .Subscribe(x => this.PropertyChanged?.Invoke(this, SingletonPropertyChangedEventArgs.Value)); // start source this.SourceDisposable = connectable.Connect(); this.ErrorsTrigger = new BehaviorSubject <IEnumerable>(this.GetErrors(null)); }
/// <summary> /// Unsubcribe all subscription. /// </summary> public void Dispose() { if (IsDisposed) { return; } IsDisposed = true; Source.OnCompleted(); Source.Dispose(); ValidationTrigger.Dispose(); SourceDisposable.Dispose(); ValidateNotifyErrorSubscription.Dispose(); if (ErrorsTrigger.IsValueCreated) { ErrorsTrigger.Value.OnCompleted(); ErrorsTrigger.Value.Dispose(); } }
/// <summary> /// <para>Set INotifyDataErrorInfo's asynchronous validation, return value is self.</para> /// </summary> /// <param name="validator">If success return IO<null>, failure return IO<IEnumerable>(Errors).</param> /// <returns>Self.</returns> public WeakReactiveProperty <T> SetValidateNotifyError(Func <IObservable <T>, IObservable <IEnumerable> > validator) { ValidatorStore.Value.Add(validator); //--- cache validation functions var validators = ValidatorStore.Value .Select(x => x(ValidationTrigger.StartWith(LatestValue))) .ToArray(); //--- use copy ValidateNotifyErrorSubscription.Disposable = Observable.CombineLatest(validators) .Select(xs => { if (xs.Count == 0) { return(null); } if (xs.All(x => x == null)) { return(null); } var strings = xs .OfType <string>() .Where(x => x != null); var others = xs .Where(x => !(x is string)) .Where(x => x != null) .SelectMany(x => x.Cast <object>()); return(strings.Concat(others)); }) .WeakSubscribe(new AnonymousObserver <IEnumerable <object> >(x => { CurrentErrors = x; var handler = ErrorsChanged; if (handler != null) { RaiseEventScheduler.Schedule( () => handler(this, SingletonDataErrorsChangedEventArgs.Value)); } ErrorsTrigger.Value.OnNext(x); })); return(this); }
public static void SetValidationTrigger(this UIElement element, ValidationTrigger value) => element.SetValue(ValidationTriggerProperty, value);
/// <summary> /// Invoke validation process. /// </summary> public void ForceValidate() => ValidationTrigger.OnNext(LatestValue);
/// <summary> /// <para>Set INotifyDataErrorInfo's asynchronous validation, return value is self.</para> /// </summary> /// <param name="validator">If success return IO<null>, failure return IO<IEnumerable>(Errors).</param> /// <returns>Self.</returns> public ReactiveProperty <T> SetValidateNotifyError(Func <IObservable <T>, IObservable <IEnumerable?> > validator) { ValidatorStore.Value.Add(validator); //--- cache validation functions var validators = ValidatorStore.Value .Select(x => x(IsIgnoreInitialValidationError ? ValidationTrigger : ValidationTrigger.StartWith(LatestValue))) .ToArray(); //--- use copy ValidateNotifyErrorSubscription.Disposable = Observable .CombineLatest(validators) .Select(xs => { if (xs.Count == 0) { return(null); } if (xs.All(x => x == null)) { return(null); } var strings = xs .Where(x => x != null) .OfType <string>(); var others = xs .Where(x => x is not string) .Where(x => x != null) .SelectMany(x => x !.Cast <object?>()); return(strings.Concat(others)); }) .Subscribe(x => { var prevHasErrors = HasErrors; CurrentErrors = x; var currentHasErrors = HasErrors; var handler = ErrorsChanged; if (handler != null) { RaiseEventScheduler.Schedule(() => handler(this, SingletonDataErrorsChangedEventArgs.Value)); } var propertyChangedHandler = PropertyChanged; if (prevHasErrors != currentHasErrors && propertyChangedHandler != null) { RaiseEventScheduler.Schedule(() => propertyChangedHandler(this, SingletonPropertyChangedEventArgs.HasErrors)); } ErrorsTrigger.Value.OnNext(x); }); return(this); }
public static void SetValidationTrigger(this UIElement element, ValidationTrigger value) => element.SetValue(ValidationTriggerProperty, value);