void setupRx(IEnumerable <T> initialContents = null, IScheduler scheduler = null, double resetChangeThreshold = 0.3) { scheduler = scheduler ?? RxApp.DeferredScheduler; _inner = _inner ?? new List <T>(); _changing = new Subject <NotifyCollectionChangedEventArgs>(); _changing.Where(_ => CollectionChanging != null && _suppressionRefCount == 0).Subscribe(x => CollectionChanging(this, x)); _changed = new Subject <NotifyCollectionChangedEventArgs>(); _changed.Where(_ => CollectionChanged != null && _suppressionRefCount == 0).Subscribe(x => CollectionChanged(this, x)); ResetChangeThreshold = resetChangeThreshold; _beforeItemsAdded = new Lazy <Subject <T> >(() => new Subject <T>()); _itemsAdded = new Lazy <Subject <T> >(() => new Subject <T>()); _beforeItemsRemoved = new Lazy <Subject <T> >(() => new Subject <T>()); _itemsRemoved = new Lazy <Subject <T> >(() => new Subject <T>()); _itemChanging = new Lazy <Subject <IObservedChange <T, object> > >(() => new Subject <IObservedChange <T, object> >()); _itemChanged = new Lazy <Subject <IObservedChange <T, object> > >(() => new Subject <IObservedChange <T, object> >()); // NB: We have to do this instead of initializing _inner so that // Collection<T>'s accounting is correct foreach (var item in initialContents ?? Enumerable.Empty <T>()) { Add(item); } // NB: ObservableCollection has a Secret Handshake with WPF where // they fire an INPC notification with the token "Item[]". Emulate // it here CollectionCountChanging.Subscribe(_ => { if (PropertyChanging != null) { PropertyChanging(this, new PropertyChangingEventArgs("Count")); } }); CollectionCountChanged.Subscribe(_ => { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs("Count")); } }); Changing.Subscribe(_ => { if (PropertyChanging != null) { PropertyChanging(this, new PropertyChangingEventArgs("Item[]")); } }); Changed.Subscribe(_ => { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs("Item[]")); } }); }
void setupRx(IEnumerable <T> initialContents = null, IScheduler scheduler = null, double resetChangeThreshold = 0.3) { if (rxObjectsSetup) { return; } scheduler = scheduler ?? RxApp.DeferredScheduler; _inner = _inner ?? new List <T>(); _changing = new Subject <NotifyCollectionChangedEventArgs>(); _changing.Subscribe(raiseCollectionChanging); _changed = new Subject <NotifyCollectionChangedEventArgs>(); _changed.Subscribe(raiseCollectionChanged); ResetChangeThreshold = resetChangeThreshold; _beforeItemsAdded = new Lazy <Subject <T> >(() => new Subject <T>()); _itemsAdded = new Lazy <Subject <T> >(() => new Subject <T>()); _beforeItemsRemoved = new Lazy <Subject <T> >(() => new Subject <T>()); _itemsRemoved = new Lazy <Subject <T> >(() => new Subject <T>()); _itemChanging = new Lazy <Subject <IObservedChange <T, object> > >(() => new Subject <IObservedChange <T, object> >()); _itemChanged = new Lazy <Subject <IObservedChange <T, object> > >(() => new Subject <IObservedChange <T, object> >()); _beforeItemsMoved = new Lazy <Subject <IMoveInfo <T> > >(() => new Subject <IMoveInfo <T> >()); _itemsMoved = new Lazy <Subject <IMoveInfo <T> > >(() => new Subject <IMoveInfo <T> >()); // NB: We have to do this instead of initializing _inner so that // Collection<T>'s accounting is correct foreach (var item in initialContents ?? Enumerable.Empty <T>()) { Add(item); } // NB: ObservableCollection has a Secret Handshake with WPF where // they fire an INPC notification with the token "Item[]". Emulate // it here CollectionCountChanging.Select(x => new PropertyChangingEventArgs("Count")).Subscribe(this.raisePropertyChanging); CollectionCountChanged.Select(x => new PropertyChangedEventArgs("Count")).Subscribe(this.raisePropertyChanged); Changing.Select(x => new PropertyChangingEventArgs("Item[]")).Subscribe(this.raisePropertyChanging); Changed.Select(x => new PropertyChangedEventArgs("Item[]")).Subscribe(this.raisePropertyChanged); rxObjectsSetup = true; }