private void OnChange(IRealmCollection <T> sender, ChangeSet change, Exception error) { if (error != null) { Realm.NotifyError(error); } else if (change != null) { if (change.Moves.Length > 0 && change.Moves.Length == change.InsertedIndices.Length && change.Moves.Length == change.DeletedIndices.Length) { var ordered = change.Moves.OrderBy(m => m.From); var movedPositions = -1; var isConsecutiveMove = true; foreach (var item in ordered) { if (movedPositions == -1) { movedPositions = item.To - item.From; } else if (item.To - item.From != movedPositions) { isConsecutiveMove = false; break; } } if (isConsecutiveMove) { var initialItem = ordered.First(); var movedItems = Enumerable.Range(initialItem.To, change.Moves.Length) .Select(i => sender[i]) .ToList(); RaiseCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Move, movedItems, initialItem.To, initialItem.From)); } else { RaiseCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); } RaisePropertyChanged(); return; } var raiseRemoved = TryGetConsecutive(change.DeletedIndices, _ => default(T), out var removedItems, out var removedStartIndex); var raiseAdded = TryGetConsecutive(change.InsertedIndices, i => this[i], out var addedItems, out var addedStartIndex); if (raiseAdded || raiseRemoved) { if ((raiseAdded && raiseRemoved) || (raiseAdded && addedItems == null) || (raiseRemoved && removedItems == null)) { RaiseCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); RaisePropertyChanged(); return; } if (removedItems != null) { RaiseCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, removedItems, removedStartIndex)); RaisePropertyChanged(); } if (addedItems != null) { RaiseCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, addedItems, addedStartIndex)); RaisePropertyChanged(); } } } }