Exemplo n.º 1
0
        void sectionCollectionChanged(int section, IList <NotifyCollectionChangedEventArgs> xs)
        {
            if (xs.Count == 0)
            {
                return;
            }

            var resetOnlyNotification = new [] { new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset) };

            this.Log().Info("Changed contents: [{0}]", String.Join(",", xs.Select(x => x.Action.ToString())));

            if (xs.Any(x => x.Action == NotifyCollectionChangedAction.Reset))
            {
                this.Log().Info("About to call ReloadData");
                adapter.ReloadData();

                didPerformUpdates.OnNext(resetOnlyNotification);
                return;
            }

            var updates           = xs.Select(ea => Tuple.Create(ea, getChangedIndexes(ea))).ToList();
            var allChangedIndexes = updates.SelectMany(u => u.Item2).ToList();

            // Detect if we're changing the same cell more than
            // once - if so, issue a reset and be done

            if (allChangedIndexes.Count != allChangedIndexes.Distinct().Count())
            {
                this.Log().Info("Detected a dupe in the changelist. Issuing Reset");
                adapter.ReloadData();

                didPerformUpdates.OnNext(resetOnlyNotification);
                return;
            }

            this.Log().Info("Beginning update");
            adapter.PerformBatchUpdates(() => {
                foreach (var update in updates.AsEnumerable().Reverse())
                {
                    var changeAction   = update.Item1.Action;
                    var changedIndexes = update.Item2;

                    switch (changeAction)
                    {
                    case NotifyCollectionChangedAction.Add:
                        doUpdate(adapter.InsertItems, changedIndexes, section);
                        break;

                    case NotifyCollectionChangedAction.Remove:
                        doUpdate(adapter.DeleteItems, changedIndexes, section);
                        break;

                    case NotifyCollectionChangedAction.Replace:
                        doUpdate(adapter.ReloadItems, changedIndexes, section);
                        break;

                    case NotifyCollectionChangedAction.Move:
                        // NB: ReactiveList currently only supports single-item
                        // moves
                        var ea = update.Item1;
                        this.Log().Info("Calling MoveRow: {0}-{1} => {0}{2}", section, ea.OldStartingIndex, ea.NewStartingIndex);

                        adapter.MoveItem(
                            NSIndexPath.FromRowSection(ea.OldStartingIndex, section),
                            NSIndexPath.FromRowSection(ea.NewStartingIndex, section));
                        break;

                    default:
                        this.Log().Info("Unknown Action: {0}", changeAction);
                        break;
                    }
                }

                this.Log().Info("Ending update");
                didPerformUpdates.OnNext(xs);
            });
        }
Exemplo n.º 2
0
        public CommonReactiveSource(
            IUICollViewAdapter <TUIView, TUIViewCell> adapter,
            IEnumerable <ISectionInformation <TUIView, TUIViewCell> > sectionInfo)
        {
            this.adapter     = adapter;
            this.sectionInfo = sectionInfo.ToList();

            for (int i = 0; i < this.sectionInfo.Count; i++)
            {
                var current = this.sectionInfo[i].Collection;

                var section = i;
                var disp    = current.Changed.Buffer(TimeSpan.FromMilliseconds(250), RxApp.MainThreadScheduler).Subscribe(xs => {
                    if (xs.Count == 0)
                    {
                        return;
                    }

                    var resetOnlyNotification = new [] { new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset) };

                    this.Log().Info("Changed contents: [{0}]", String.Join(",", xs.Select(x => x.Action.ToString())));
                    if (xs.Any(x => x.Action == NotifyCollectionChangedAction.Reset))
                    {
                        this.Log().Info("About to call ReloadData");
                        adapter.ReloadData();
                        didPerformUpdates.OnNext(resetOnlyNotification);
                        return;
                    }

                    var updates           = xs.Select(ea => Tuple.Create(ea, getChangedIndexes(ea))).ToList();
                    var allChangedIndexes = updates.SelectMany(u => u.Item2).ToList();
                    // Detect if we're changing the same cell more than
                    // once - if so, issue a reset and be done
                    if (allChangedIndexes.Count != allChangedIndexes.Distinct().Count())
                    {
                        this.Log().Info("Detected a dupe in the changelist. Issuing Reset");
                        adapter.ReloadData();
                        didPerformUpdates.OnNext(resetOnlyNotification);
                        return;
                    }

                    this.Log().Info("Beginning update");
                    adapter.PerformBatchUpdates(() => {
                        foreach (var update in updates.AsEnumerable().Reverse())
                        {
                            var changeAction   = update.Item1.Action;
                            var changedIndexes = update.Item2;
                            switch (changeAction)
                            {
                            case NotifyCollectionChangedAction.Add:
                                doUpdate(adapter.InsertItems, changedIndexes, section);
                                break;

                            case NotifyCollectionChangedAction.Remove:
                                doUpdate(adapter.DeleteItems, changedIndexes, section);
                                break;

                            case NotifyCollectionChangedAction.Replace:
                                doUpdate(adapter.ReloadItems, changedIndexes, section);
                                break;

                            case NotifyCollectionChangedAction.Move:
                                // NB: ReactiveList currently only supports single-item
                                // moves
                                var ea = update.Item1;
                                this.Log().Info("Calling MoveRow: {0}-{1} => {0}{2}", section, ea.OldStartingIndex, ea.NewStartingIndex);

                                adapter.MoveItem(
                                    NSIndexPath.FromRowSection(ea.OldStartingIndex, section),
                                    NSIndexPath.FromRowSection(ea.NewStartingIndex, section));
                                break;

                            default:
                                this.Log().Info("Unknown Action: {0}", changeAction);
                                break;
                            }
                        }

                        this.Log().Info("Ending update");
                        didPerformUpdates.OnNext(xs);
                    });
                });

                innerDisp.Add(disp);
            }
        }