Example #1
0
        public SampleViewModel()
        {
            Items = new ReactiveList <SampleObject> ();

            var rand = new Random();

            Observable.Interval(TimeSpan.FromMilliseconds(300))
            .ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(num =>
            {
                var idx = rand.Next(Items.Count);

                var act = rand.NextDouble();
                if (act < 0.4 || idx >= Items.Count)
                {
                    Items.Insert(
                        idx,
                        new SampleObject()
                    {
                        Name = "Hallo Number " + num
                    });
                    Debug.WriteLine("Inserted " + idx);
                }
                else if (act < 0.8)
                {
                    Items [idx].Name = "Now I'm Number " + num;
                    Debug.WriteLine("Renamed " + idx);
                }
                else
                {
                    Items.RemoveAt(idx);
                    Debug.WriteLine("Removed " + idx);
                }
            });
        }
Example #2
0
        /// <summary>
        /// Takes each list produced by this observable and mirrors its contents in the target list.
        /// The target list is modified, not replaced.
        /// The type of the target list property is IReadOnlyReactiveList because it doesn't make sense to have a mutible list
        /// if this binding keeps changing the contents of the list, but the type of the actual object should be ReactiveList
        /// so the list can be modified by this binding.
        /// </summary>
        /// <typeparam name="TObj">The type of viewmodel</typeparam>
        /// <typeparam name="TListItem">The type of object contained in the list</typeparam>
        /// <param name="data">The observable to take lists from.</param>
        /// <param name="target">The viewmodel that is used as a base for finding the target list property</param>
        /// <param name="property">The IReactiveList property that will be modified.</param>
        /// <returns>A disposable to break the binding</returns>
        public static IDisposable BindListContents <TObj, TListItem>(this IObservable <IList <TListItem> > data,
                                                                     TObj target, Expression <Func <TObj, IReadOnlyReactiveList <TListItem> > > property) where TObj : class
        {
            IObservable <IReadOnlyReactiveList <TListItem> > targetListObservable = target.WhenAnyValue(property);

            return(Observable.CombineLatest(targetListObservable, data, (a, b) => (TargetList: a, SourceList: b))
                   .Subscribe(t =>
            {
                IReactiveList <TListItem> latestTargetList = t.TargetList as IReactiveList <TListItem>;
                IList <TListItem> latestData = t.SourceList;

                if (latestTargetList == null)
                {
                    return;
                }

                if (latestData == null)
                {
                    latestTargetList.Clear();
                    return;
                }

                var changes = LongestCommonSubsequence.GetChanges(latestTargetList, latestData).ToArray();
                if (changes.Length == 0)
                {
                    return;
                }

                using (changes.Length > 1 ? latestTargetList.SuppressChangeNotifications() : Disposable.Empty)
                {
                    foreach (var(index, item, changeType) in changes)
                    {
                        if (changeType == LongestCommonSubsequence.ChangeType.Removed)
                        {
                            latestTargetList.RemoveAt(index);
                        }
                        else if (changeType == LongestCommonSubsequence.ChangeType.Added)
                        {
                            latestTargetList.Insert(index, item);
                        }
                    }
                }
            }));
        }