Example #1
0
 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);
     }
 }
Example #2
0
        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);
        }
Example #3
0
        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();
            }
        }
Example #4
0
        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));
                }
            }
        }