Пример #1
0
        /// <summary>
        /// Reattach the property to the property in the specified object.
        /// </summary>
        public void Connect(object list)
        {
            Argument.NotNull(() => list);

            if (this.list != null)
            {
                Disconnect();
            }

            this.list = (IList)list;
            this.previousCollectionContent = this.list.Cast <object>().ToArray();
            this.bindings = bindingsFactory.CreateListBindings(this.list).ToList();

            var notifyCollectionChanged = this.list as INotifyCollectionChanged;

            if (notifyCollectionChanged != null)
            {
                listSubscription = notifyCollectionChanged
                                   .OnAnyCollectionChanges()
                                   .Subscribe(e =>
                {
                    switch (e.Action)
                    {
                    case NotifyCollectionChangedAction.Add:
                        {
                            bindings
                            .Where(b => b.ItemIndex >= e.NewStartingIndex + e.NewItems.Count - 1)
                            .Each(b => b.ItemIndex = b.ItemIndex + e.NewItems.Count);

                            e.NewItems.Cast <object>()
                            .Select((i, index) =>
                            {
                                return(bindingsFactory.CreateListBinding(i, e.NewStartingIndex + index, this.list));
                            })
                            .Each(b => bindings.Add(b));
                        }
                        break;

                    case NotifyCollectionChangedAction.Remove:
                        {
                            var bindingsToRemove = bindings
                                                   .Where(b =>
                                                          b.ItemIndex >= e.OldStartingIndex &&
                                                          b.ItemIndex < e.OldStartingIndex + e.OldItems.Count);

                            bindingsToRemove.Each(b => b.Disconnect());
                            bindings.RemoveAll(b => bindingsToRemove.Any(btr => btr == b));

                            bindings
                            .Where(b => b.ItemIndex >= e.OldStartingIndex + e.OldItems.Count)
                            .Each(b => b.ItemIndex = b.ItemIndex - e.OldItems.Count);
                        }
                        break;

                    case NotifyCollectionChangedAction.Reset:
                        {
                            bindings.Each(b => b.Disconnect());

                            bindings.Clear();
                        }
                        break;

                    default:
                        {
                            throw new ApplicationException("Unsupported operation for a bound list: " +
                                                           Enum.GetName(typeof(NotifyCollectionChangedAction), e.Action));
                        }
                    }

                    // This does not account for multiple items added or removed.
                    var binding = bindings.Where(b => b.ItemIndex == e.NewStartingIndex).FirstOrDefault();

                    if (e.Action != NotifyCollectionChangedAction.Add || binding != null)
                    {
                        listCollectionChangedEvents.OnNext(new BoundCollectionChangedEventArgs(null, e, binding, previousCollectionContent));
                    }

                    // Update previous collection content each time the list changes.
                    previousCollectionContent = this.list.Cast <object>().ToArray();

                    BindEventStreams();
                });
            }

            BindEventStreams();
        }