private IChangeSet <T> Page(IChangeSet <T> changeset = null) { if (changeset != null) { _all.Clone(changeset); } var previous = _paged; int pages = CalculatePages(); int page = _parameters.Page > pages ? pages : _parameters.Page; int skip = _parameters.Size * (page - 1); var current = _all.Skip(skip) .Take(_parameters.Size) .ToList(); var adds = current.Except(previous); var removes = previous.Except(current); _paged.RemoveMany(removes); adds.ForEach(t => { var index = current.IndexOf(t); _paged.Insert(index, t); }); var startIndex = skip; var moves = changeset.EmptyIfNull() .Where(change => change.Reason == ListChangeReason.Moved && change.MovedWithinRange(startIndex, startIndex + _parameters.Size)); foreach (var change in moves) { //check whether an item has moved within the same page var currentIndex = change.Item.CurrentIndex - startIndex; var previousIndex = change.Item.PreviousIndex - startIndex; _paged.Move(previousIndex, currentIndex); } //find replaces [Is this ever the case that it can be reached] for (int i = 0; i < current.Count; i++) { var currentItem = current[i]; var previousItem = previous[i]; if (ReferenceEquals(currentItem, previousItem)) { continue; } var index = _paged.IndexOf(currentItem); _paged.Move(i, index); } return(_paged.CaptureChanges()); }
private IChangeSet <T> Virtualise(List <T> all, ChangeAwareList <T> virtualised, IChangeSet <T> changeset = null) { if (changeset != null) { all.Clone(changeset); } var previous = virtualised; var current = all.Skip(_parameters.StartIndex) .Take(_parameters.Size) .ToList(); var adds = current.Except(previous); var removes = previous.Except(current); virtualised.RemoveMany(removes); adds.ForEach(t => { var index = current.IndexOf(t); virtualised.Insert(index, t); }); var moves = changeset.EmptyIfNull() .Where(change => change.Reason == ListChangeReason.Moved && change.MovedWithinRange(_parameters.StartIndex, _parameters.StartIndex + _parameters.Size)); foreach (var change in moves) { //check whether an item has moved within the same page var currentIndex = change.Item.CurrentIndex - _parameters.StartIndex; var previousIndex = change.Item.PreviousIndex - _parameters.StartIndex; virtualised.Move(previousIndex, currentIndex); } //find replaces [Is this ever the case that it can be reached] for (var i = 0; i < current.Count; i++) { var currentItem = current[i]; var previousItem = previous[i]; if (ReferenceEquals(currentItem, previousItem)) { continue; } var index = virtualised.IndexOf(currentItem); virtualised.Move(i, index); } return(virtualised.CaptureChanges()); }
private IChangeSet <T> Reorder(ChangeAwareList <T> target) { int index = -1; var sorted = target.OrderBy(t => t, _comparer).ToList(); foreach (var item in sorted) { index++; var existing = target[index]; //if item is in the same place, if (ReferenceEquals(item, existing)) { continue; } //Cannot use binary search as Resort is implicit of a mutable change var old = target.IndexOf(item); target.Move(old, index); } return(target.CaptureChanges()); }