private static IObservable <T> ObserveFullPropertyPathCore <TNotifier, TProperty, T>(this TNotifier source, NotifyingPath <TNotifier, TProperty> notifyingPath, Func <object?, PropertyChangedEventArgs, T> create, bool signalInitial = true) where TNotifier : class, INotifyPropertyChanged { if (signalInitial) { return(Observable.Return( create( notifyingPath.SourceAndValue(source).Source, CachedEventArgs.GetOrCreatePropertyChangedEventArgs(string.Empty))) .Concat(source.ObserveFullPropertyPathCore(notifyingPath, create, signalInitial: false))); } return(Observable.Create <T>( o => { var tracker = notifyingPath.CreateTracker(source); void Handler(object sender, PropertyChangedEventArgs e) => o.OnNext(create(sender, e)); foreach (var propertyTracker in tracker) { propertyTracker.TrackedPropertyChanged += Handler; } return Disposable.Create( () => { foreach (var propertyTracker in tracker) { propertyTracker.TrackedPropertyChanged -= Handler; } tracker.Dispose(); }); })); }
private static IObservable <T> ObservePropertyChangedCore <TNotifier, TProperty, T>( this TNotifier source, NotifyingPath <TNotifier, TProperty> notifyingPath, Func <object, PropertyChangedEventArgs, T> create, bool signalInitial = true) where TNotifier : class, INotifyPropertyChanged { if (signalInitial) { return(Observable.Return( create( notifyingPath.SourceAndValue(source).Source, CachedEventArgs.GetOrCreatePropertyChangedEventArgs(string.Empty))) .Concat(source.ObservePropertyChangedCore(notifyingPath, create, signalInitial: false))); } if (notifyingPath.Count > 1) { return(Observable.Create <T>( o => { var tracker = notifyingPath.CreateTracker(source); void Handler(IPropertyTracker _, object sender, PropertyChangedEventArgs e, SourceAndValue <INotifyPropertyChanged, TProperty> __) => o.OnNext(create(sender, e)); tracker.TrackedPropertyChanged += Handler; return new CompositeDisposable(2) { tracker, Disposable.Create(() => tracker.TrackedPropertyChanged -= Handler), }; })); } return(ObservePropertyChangedCore(source, notifyingPath.Last.Property.Name, create, signalInitial: false)); }
private static IObservable <T> ObserveValueCore <TNotifier, TProperty, T>( this TNotifier source, NotifyingPath <TNotifier, TProperty> notifyingPath, Func <object?, PropertyChangedEventArgs, Maybe <TProperty>, T> create, bool signalInitial = true) where TNotifier : class, INotifyPropertyChanged { if (signalInitial) { return(Observable.Defer( () => { var sourceAndValue = notifyingPath.SourceAndValue(source); return Observable.Return( create( sourceAndValue.Source, CachedEventArgs.GetOrCreatePropertyChangedEventArgs(string.Empty), sourceAndValue.Value)); }) .Concat(source.ObserveValueCore(notifyingPath, create, signalInitial: false))); } if (notifyingPath.Count > 1) { return(Observable.Create <T>( o => { var tracker = notifyingPath.CreateTracker(source); tracker.TrackedPropertyChanged += Handler; return new CompositeDisposable(2) { tracker, Disposable.Create(() => tracker.TrackedPropertyChanged -= Handler), }; void Handler(IPropertyTracker _, object sender, PropertyChangedEventArgs args, SourceAndValue <INotifyPropertyChanged?, TProperty> sourceAndValue) { o.OnNext(create(sender, args, sourceAndValue.Value)); } })); } return(Observable.Create <T>( o => { void Handler(object sender, PropertyChangedEventArgs e) { if (e.IsMatch(notifyingPath.Last.Property)) { var value = notifyingPath.Last.GetMaybe(sender); o.OnNext(create(sender, e, value)); } } source.PropertyChanged += Handler; return Disposable.Create(() => source.PropertyChanged -= Handler); })); }