private static bool SyncPrivate(FlowObservableCollection <T> currentItems, FlowObservableCollection <T> updateItems, bool notify) { currentItems?.OnCollectionChangedSuspend(); var itemsAdded = notify ? new List <T>() : null; var itemsRemoved = notify ? new List <T>() : null; //var itemsMoved = notify ? new List<T>() : null; //var itemsMovedIndexes = notify ? new List<Tuple<int, int>>() : null; bool structureIsChanged = false; bool forceReset = false; var flowGroup = updateItems.FirstOrDefault() as FlowGroup; if (flowGroup != null) { var result = updateItems .Join(currentItems, k => ((FlowGroup)(object)k).Key, i => ((FlowGroup)(object)i).Key, (k, i) => i) .ToList(); for (int i = 0; i < result.Count; i++) { var oldGroup = currentItems[i] as FlowGroup; var newGroup = result[i] as FlowGroup; if (oldGroup.Key != newGroup.Key) { forceReset = true; currentItems[i] = (T)(object)newGroup; } } } for (int i = 0; i < updateItems.Count; i++) { var item = updateItems[i]; if (currentItems.Count <= i) { structureIsChanged = true; currentItems.Add(item); itemsAdded?.Add(item); } else { var itemList = item as FlowObservableCollection <object>; var currentItem = currentItems[i]; var currentItemList = currentItem as FlowObservableCollection <object>; if (itemList != null && currentItemList != null) { if (currentItemList.Sync(itemList, false)) { structureIsChanged = true; } } else if (structureIsChanged) { currentItems[i] = item; } else if ((object)item != (object)currentItem) { structureIsChanged = true; currentItems[i] = item; } } } while (currentItems.Count > updateItems.Count) { structureIsChanged = true; itemsRemoved?.Add(currentItems[currentItems.Count - 1]); currentItems.RemoveAt(currentItems.Count - 1); } if (forceReset || structureIsChanged) { if (!forceReset && itemsAdded != null && itemsRemoved == null && itemsAdded.Count < 100) { currentItems?.OnCollectionChangedCancel(); currentItems?.NotifyCollectionChanged( new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, itemsAdded)); } else if (!forceReset && itemsRemoved != null && itemsAdded == null && itemsRemoved.Count < 100) { currentItems?.NotifyCollectionChanged( new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, itemsRemoved)); } else { currentItems?.OnCollectionChangedResume(); } } else { currentItems?.OnCollectionChangedCancel(); } return(structureIsChanged); }
internal bool Sync(FlowObservableCollection <T> newItems, bool notify = true) { return(SyncPrivate(this, newItems, notify)); }