Exemplo n.º 1
0
        /// <summary>
        /// Gets or sets the element at the specified index.
        /// </summary>
        /// <param name="index">The zero-based index of the element to get or set.</param>
        /// <returns>The element at the specified index.</returns>
        /// <exception cref="System.ArgumentOutOfRangeException"><paramref name="index"/> is not a valid index in the list.</exception>
        public T this[int index]
        {
            get
            {
                lock (gate)
                {
                    EnsureNotDisposed();
                    EnsureNotFaulted();

                    Contract.Assume(index < list.Count);

                    return(list[index]);
                }
            }
            set
            {
                lock (gate)
                {
                    EnsureNotDisposed();

                    if (EnsureNotStopped())
                    {
                        Contract.Assume(index < list.Count);

                        T previous = list[index];

                        list[index] = value;

                        subject.OnNext(CollectionNotification.CreateOnReplaced(previous, value));
                    }
                }
            }
        }
Exemplo n.º 2
0
        private void SetInternal(KeyValuePair <TKey, TValue> newPair)
        {
            if (dictionary.Contains(newPair.Key))
            {
                int index = dictionary.IndexOf(newPair.Key);

                Contract.Assume(index >= 0);

                var oldPair = dictionary[index];

                dictionary[index] = newPair;

                OnPropertyChanged(new PropertyChangedEventArgs("Values"));
                OnPropertyChanged(new PropertyChangedEventArgs("Item[]"));

#if !PORT_40
                OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, newPair, oldPair, index));
#endif

                subject.OnNext(CollectionNotification.CreateOnReplaced(oldPair, newPair));
            }
            else
            {
                AddInternal(newPair);
            }
        }
        /// <summary>
        /// Converts <see cref="INotifyCollectionChanged.CollectionChanged"/> events into an observable sequence of <see cref="CollectionNotification{T}"/>.
        /// </summary>
        /// <typeparam name="T">The object that provides notification information.</typeparam>
        /// <param name="source">An implementation of <see cref="INotifyCollectionChanged"/> that raises events when a collection changes.</param>
        /// <remarks>
        /// An <see cref="NotifyCollectionChangedAction.Add"/> event is projected into zero or more <see cref="CollectionNotificationKind.OnAdded"/> notifications.
        /// A <see cref="NotifyCollectionChangedAction.Remove"/> event is projected into zero or more <see cref="CollectionNotificationKind.OnRemoved"/> notifications.
        /// A <see cref="NotifyCollectionChangedAction.Move"/> event is projected into zero or more <see cref="CollectionNotificationKind.OnReplaced"/> notifications
        /// where <see cref="CollectionNotification{T}.Value"/> and <see cref="CollectionNotification{T}.ReplacedValue"/> refer to the same value.
        /// A <see cref="NotifyCollectionChangedAction.Replace"/> event is projected into zero or more <see cref="CollectionNotificationKind.OnReplaced"/> notifications.
        /// A <see cref="NotifyCollectionChangedAction.Reset"/> event is projected into a single <see cref="CollectionNotificationKind.OnCleared"/> notification.
        /// </remarks>
        /// <returns>An observable sequence of <see cref="CollectionNotification{T}"/> objects corresponding to raised events.</returns>
#else
        /// <summary>
        /// Converts <see cref="INotifyCollectionChanged.CollectionChanged"/> events into an observable sequence of <see cref="CollectionNotification{T}"/>.
        /// </summary>
        /// <typeparam name="T">The object that provides notification information.</typeparam>
        /// <param name="source">An implementation of <see cref="INotifyCollectionChanged"/> that raises events when a collection changes.</param>
        /// <remarks>
        /// An <see cref="NotifyCollectionChangedAction.Add"/> event is projected into zero or more <see cref="CollectionNotificationKind.OnAdded"/> notifications.
        /// A <see cref="NotifyCollectionChangedAction.Remove"/> event is projected into zero or more <see cref="CollectionNotificationKind.OnRemoved"/> notifications.
        /// A <see cref="NotifyCollectionChangedAction.Replace"/> event is projected into zero or more <see cref="CollectionNotificationKind.OnReplaced"/> notifications.
        /// A <see cref="NotifyCollectionChangedAction.Reset"/> event is projected into a single <see cref="CollectionNotificationKind.OnCleared"/> notification.
        /// </remarks>
        /// <returns>An observable sequence of <see cref="CollectionNotification{T}"/> objects corresponding to raised events.</returns>
#endif
        public static IObservable <CollectionNotification <T> > AsCollectionNotifications <T>(this INotifyCollectionChanged source)
        {
            Contract.Requires(source != null);
            Contract.Ensures(Contract.Result <IObservable <CollectionNotification <T> > >() != null);

            return(Observable.FromEventPattern <NotifyCollectionChangedEventHandler, NotifyCollectionChangedEventArgs>(
                       eh => source.CollectionChanged += eh,
                       eh => source.CollectionChanged -= eh)
                   .SelectMany(e =>
            {
                var args = e.EventArgs;

                switch (args.Action)
                {
                case NotifyCollectionChangedAction.Add:
                    return EnsureSequence <T>(args.NewItems).Select(CollectionNotification.CreateOnAdded).ToObservable();

                case NotifyCollectionChangedAction.Remove:
                    return EnsureSequence <T>(args.OldItems).Select(CollectionNotification.CreateOnRemoved).ToObservable();

#if !SILVERLIGHT
                case NotifyCollectionChangedAction.Move:
                    return EnsureSequence <T>(args.OldItems).Select(value => CollectionNotification.CreateOnReplaced(value, value)).ToObservable();
#endif
                case NotifyCollectionChangedAction.Replace:
                    return EnsureSequence <T>(args.NewItems)
                    .Zip(
                        EnsureSequence <T>(args.OldItems),
                        (newValue, oldValue) => CollectionNotification.CreateOnReplaced(oldValue, newValue))
                    .ToObservable();

                case NotifyCollectionChangedAction.Reset:
                    return Observable.Return(CollectionNotification.CreateOnCleared <T>());

                default:
                    throw new InvalidOperationException();
                }
            }));
        }
Exemplo n.º 4
0
        protected override void Main()
        {
            var source = new DictionarySubject <string, CustomValue>();

            var monitorKeys = new[] { "A", "C", "D", "E", "F", "G" };

            // PropertyChanges doesn't work on KeyValuePair because it doesn't have any property change events.
            // So we must strip off the key and create a sequence of collection notifications for the values only.
            using (source
                   .Where(
                       exists: _ => false,
                       onAdded: added => monitorKeys.Contains(added.Key),
                       onReplaced: (replaced, added) => monitorKeys.Contains(replaced.Key) && monitorKeys.Contains(added.Key),
                       onRemoved: removed => monitorKeys.Contains(removed.Key),
                       onCleared: () => false)
                   .Select(
                       _ => null,
                       added => CollectionNotification.CreateOnAdded(added.Value),
                       (replaced, added) => CollectionNotification.CreateOnReplaced(replaced.Value, added.Value),
                       removed => CollectionNotification.CreateOnRemoved(removed.Value),
                       () => null)
                   .PropertyChanges()
                   .Select(e => new { Object = (CustomValue)e.Sender, Property = e.EventArgs.PropertyName })
                   .Subscribe(value => TraceLine("Changed {0}: {1}", value.Property, value.Object)))
            {
                var a = new CustomValue("A");
                var b = new CustomValue("B");
                var c = new CustomValue("C");

                source.Add(a.Name, a);
                source.Add(b.Name, b);
                source.Add(c.Name, c);

                a.Child = new CustomValue("D");
                b.Child = new CustomValue("E");
                c.Child = new CustomValue("F");

                a.Child.Child = new CustomValue("G");

                a.Number = 1;
                b.Number = 1;
                c.Number = 1;

                a.Child.Number = 100;
                b.Child.Number = 101;
                c.Child.Number = 102;

                var child      = a.Child;
                var grandchild = child.Child;

                grandchild.Number = 103;

                child.Child = null;

                grandchild.Number = 104;

                child.Number = 105;

                a.Child = null;

                child.Number = 106;

                source.Remove(a.Name);

                a.Number = 2;
                b.Number = 2;
                c.Number = 2;

                child.Number   = 200;
                b.Child.Number = 201;
                c.Child.Number = 202;

                grandchild.Number = 203;

                source.Remove(b.Name);
                source.Remove(c.Name);

                a.Number = 4;
                b.Number = 4;
                c.Number = 4;

                child.Number   = 300;
                b.Child.Number = 301;
                c.Child.Number = 302;

                grandchild.Number = 303;
            }
        }