예제 #1
0
        void setupRx(IEnumerable <T> List = null)
        {
            _BeforeItemsAdded   = new ScheduledSubject <T>(RxApp.DeferredScheduler);
            _BeforeItemsRemoved = new ScheduledSubject <T>(RxApp.DeferredScheduler);
            aboutToClear        = new Subject <int>();

            if (List != null)
            {
                foreach (var v in List)
                {
                    this.Add(v);
                }
            }

            var ocChangedEvent = new Subject <NotifyCollectionChangedEventArgs>();

            CollectionChanged += (o, e) => ocChangedEvent.OnNext(e);

            _ItemsAdded = ocChangedEvent
                          .Where(x =>
                                 x.Action == NotifyCollectionChangedAction.Add ||
                                 x.Action == NotifyCollectionChangedAction.Replace)
                          .SelectMany(x =>
                                      (x.NewItems != null ? x.NewItems.OfType <T>() : Enumerable.Empty <T>())
                                      .ToObservable())
                          .Multicast(new ScheduledSubject <T>(RxApp.DeferredScheduler))
                          .PermaRef();

            _ItemsRemoved = ocChangedEvent
                            .Where(x =>
                                   x.Action == NotifyCollectionChangedAction.Remove ||
                                   x.Action == NotifyCollectionChangedAction.Replace)
                            .SelectMany(x =>
                                        (x.OldItems != null ? x.OldItems.OfType <T>() : Enumerable.Empty <T>())
                                        .ToObservable())
                            .Multicast(new ScheduledSubject <T>(RxApp.DeferredScheduler))
                            .PermaRef();

            _CollectionCountChanging = Observable.Merge(
                _BeforeItemsAdded.Select(_ => this.Count),
                _BeforeItemsRemoved.Select(_ => this.Count),
                aboutToClear
                );

            _CollectionCountChanged = ocChangedEvent
                                      .Select(x => this.Count)
                                      .DistinctUntilChanged();

            _ItemChanging = new ScheduledSubject <IObservedChange <T, object> >(RxApp.DeferredScheduler);
            _ItemChanged  = new ScheduledSubject <IObservedChange <T, object> >(RxApp.DeferredScheduler);

            // TODO: Fix up this selector nonsense once SL/WP7 gets Covariance
            _Changing = Observable.Merge(
                _BeforeItemsAdded.Select <T, IObservedChange <object, object> >(x =>
                                                                                new ObservedChange <object, object>()
            {
                PropertyName = "Items", Sender = this, Value = this
            }),
                _BeforeItemsRemoved.Select <T, IObservedChange <object, object> >(x =>
                                                                                  new ObservedChange <object, object>()
            {
                PropertyName = "Items", Sender = this, Value = this
            }),
                aboutToClear.Select <int, IObservedChange <object, object> >(x =>
                                                                             new ObservedChange <object, object>()
            {
                PropertyName = "Items", Sender = this, Value = this
            }),
                _ItemChanging.Select <IObservedChange <T, object>, IObservedChange <object, object> >(x =>
                                                                                                      new ObservedChange <object, object>()
            {
                PropertyName = x.PropertyName, Sender = x.Sender, Value = x.Value
            }));

            _Changed = Observable.Merge(
                _ItemsAdded.Select <T, IObservedChange <object, object> >(x =>
                                                                          new ObservedChange <object, object>()
            {
                PropertyName = "Items", Sender = this, Value = this
            }),
                _ItemsRemoved.Select <T, IObservedChange <object, object> >(x =>
                                                                            new ObservedChange <object, object>()
            {
                PropertyName = "Items", Sender = this, Value = this
            }),
                _ItemChanged.Select <IObservedChange <T, object>, IObservedChange <object, object> >(x =>
                                                                                                     new ObservedChange <object, object>()
            {
                PropertyName = x.PropertyName, Sender = x.Sender, Value = x.Value
            }));

            _ItemsAdded.Subscribe(x => {
                this.Log().DebugFormat("Item Added to {0:X} - {1}", this.GetHashCode(), x);
                if (propertyChangeWatchers == null)
                {
                    return;
                }
                addItemToPropertyTracking(x);
            });

            _ItemsRemoved.Subscribe(x => {
                this.Log().DebugFormat("Item removed from {0:X} - {1}", this.GetHashCode(), x);
                if (propertyChangeWatchers == null || !propertyChangeWatchers.ContainsKey(x))
                {
                    return;
                }

                removeItemFromPropertyTracking(x);
            });

#if DEBUG
            _ItemChanged.Subscribe(x =>
                                   this.Log().DebugFormat("Object {0} changed in collection {1:X}", x, this.GetHashCode()));
#endif
        }