void AddToFilteredAndGroupSorted(object item) { // If we're adding an item because of a call to the 'AddNew' method, we // if (AddToFiltered(item, true) && Grouping && CurrentAddItem == null) { RootGroup.AddInSubtree(item, Culture, GroupDescriptions); } }
public override void Refresh() { if (IsAddingNew || IsEditingItem) { throw new InvalidOperationException("Cannot refresh while adding or editing an item"); } if (DeferLevel != 0) { return; } Groups = null; RootGroup.ClearItems(); if (ActiveList != SourceCollection) { try { IgnoreFilteredListChanges = true; filteredList.Clear(); foreach (var item in SourceCollection) { AddToFiltered(item, false); } if (SortDescriptions.Count > 0) { filteredList.Sort(new PropertyComparer(SortDescriptions)); } } finally { IgnoreFilteredListChanges = false; } if (GroupDescriptions.Count > 0 && filteredList.Count > 0) { foreach (var item in filteredList) { RootGroup.AddInSubtree(item, Culture, GroupDescriptions, false); } Groups = RootGroup.Items; } } IsEmpty = ActiveList.Count == 0; IsCurrentAfterLast = CurrentPosition == ActiveList.Count || ActiveList.Count == 0; IsCurrentBeforeFirst = CurrentPosition == -1 || ActiveList.Count == 0; int index = IndexOf(CurrentItem); if (index < 0 && CurrentPosition != -1 && !IsEmpty) { index = 0; } RaiseCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset), false); MoveCurrentTo(index, true, false); }
public override void CommitNew() { if (IsEditingItem) { throw new InvalidOperationException("Cannot CommitNew while editing an item"); } if (IsAddingNew) { if (CurrentAddItem is IEditableObject) { ((IEditableObject)CurrentAddItem).EndEdit(); } RootGroup.RemoveInSubtree(CurrentAddItem); if (Filter != null && !Filter(CurrentAddItem)) { RemoveFromSourceCollection(SourceCollection.IndexOf(CurrentAddItem)); } else { // When adding a new item, we initially put it in the root group. Once it's committed // we need to place it in the correct subtree group. if (Grouping) { RootGroup.AddInSubtree(CurrentAddItem, Culture, GroupDescriptions); } // The item was not filtered out of the tree. Do we need to resort it? if (SortDescriptions.Count > 0) { // The newly added item is at the end of the array. If we're sorting, we may have to move it. // Use a binary search to figure out where the item should be in the list and put it in there. int actualIndex = filteredList.IndexOf(CurrentAddItem); int sortedIndex = filteredList.BinarySearch(0, filteredList.Count - 1, CurrentAddItem, new PropertyComparer(SortDescriptions)); if (sortedIndex < 0) { sortedIndex = ~sortedIndex; } if (actualIndex != sortedIndex) { MoveAndSelectFromSorted(actualIndex, sortedIndex, CurrentItem); } } } CurrentAddItem = null; IsAddingNew = false; UpdateCanAddNewAndRemove(); } }
public override void CommitEdit() { if (IsAddingNew) { throw new InvalidOperationException("Cannot cancel edit while adding new"); } if (IsEditingItem) { var editItem = CurrentEditItem; CurrentEditItem = null; IsEditingItem = false; if (CanCancelEdit) { ((IEditableObject)editItem).EndEdit(); CanCancelEdit = false; } UpdateCanAddNewAndRemove(); int originalIndex = IndexOf(editItem); int newIndex; // If we're filtering the item out just nuke it if (Filter != null && !Filter(editItem)) { RemoveFromFilteredAndGroup(editItem); if (CurrentItem == editItem) { MoveCurrentTo(CurrentPosition); } return; } // We could also have changed the property which sorts it if (SortDescriptions.Count > 0) { // We can't just remove the item and binary search for the correct place as that will change the // order of elements which compare as equal and breaks more tests than it fixes. We need to first // check to see if the editItem is >= than the previous one and <= the next one. If that is true // we need to do nothing. Otherwise we need to binary search either the upper or lower half and // find the new index where the editItem should be placed. if (originalIndex > 0 && Comparer.Compare(filteredList [originalIndex - 1], editItem) > 0) { newIndex = filteredList.BinarySearch(0, originalIndex, editItem, Comparer); } else if (originalIndex < (filteredList.Count - 1) && Comparer.Compare(filteredList [originalIndex + 1], editItem) < 0) { newIndex = filteredList.BinarySearch(originalIndex + 1, filteredList.Count - (originalIndex + 1), editItem, Comparer); } else { // We're already in the right place. newIndex = originalIndex; } } else { // No sorting == no index change newIndex = originalIndex; } var currentSelection = CurrentItem; if (newIndex != originalIndex) { if (newIndex < 0) { newIndex = ~newIndex; } // When we remove the element from the original index, our newIndex will be off by 1 as everything // gets shuffled down so decrement it here. if (newIndex > originalIndex) { newIndex--; } DeferCurrentChanged = true; filteredList.RemoveAt(originalIndex); filteredList.Insert(newIndex, editItem); DeferCurrentChanged = false; } // We may have edited the property which controls which group the item is in // so re-seat it if (Grouping) { DeferCurrentChanged = true; RootGroup.RemoveInSubtree(editItem); RootGroup.AddInSubtree(editItem, Culture, GroupDescriptions); DeferCurrentChanged = false; MoveCurrentTo(IndexOf(currentSelection) + 1); } else if (originalIndex != newIndex) { MoveCurrentTo(IndexOf(currentSelection)); } } }