private void handleSourceCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { checkConsistent(sender, e); if (!_rootSourceWrapper && _lastProcessedSourceChangeMarker == _sourceAsList.ChangeMarkerField) { return; } _handledEventSender = sender; _handledEventArgs = e; _lastProcessedSourceChangeMarker = !_lastProcessedSourceChangeMarker; switch (e.Action) { case NotifyCollectionChangedAction.Add: _isConsistent = false; int newSourceIndex = e.NewStartingIndex; TSourceItem addedSourceItem = _sourceAsList[newSourceIndex]; Position newItemPosition = null; Position nextItemPosition; int?newFilteredIndex = null; getNewExpressionWatcherAndPredicateFunc(addedSourceItem, out ExpressionWatcher newWatcher, out Func <bool> newPredicateFunc); if (newSourceIndex < _itemInfos.Count) { ItemInfo oldItemInfo = _itemInfos[newSourceIndex]; Position oldItemInfoNextFilteredItemPosition = oldItemInfo.NextFilteredItemPosition; Position oldItemInfoFilteredPosition = oldItemInfo.FilteredPosition; if (applyPredicate(addedSourceItem, newPredicateFunc)) { if (oldItemInfoFilteredPosition == null) { newItemPosition = _filteredPositions.Insert(oldItemInfoNextFilteredItemPosition.Index); nextItemPosition = oldItemInfoNextFilteredItemPosition; newFilteredIndex = newItemPosition.Index; } else { int filteredIndex = oldItemInfoFilteredPosition.Index; newFilteredIndex = filteredIndex; newItemPosition = _filteredPositions.Insert(filteredIndex); nextItemPosition = oldItemInfoFilteredPosition; } modifyNextFilteredItemIndex(newSourceIndex, newItemPosition); } else { nextItemPosition = oldItemInfoFilteredPosition ?? oldItemInfoNextFilteredItemPosition; } } else { if (applyPredicate(addedSourceItem, newPredicateFunc)) { newItemPosition = _filteredPositions.List[Count]; newFilteredIndex = Count; nextItemPosition = _filteredPositions.Add(); } else { //здесь newPositionIndex = null; так и должно быть nextItemPosition = _filteredPositions.List[Count]; } } registerSourceItem(addedSourceItem, newSourceIndex, newItemPosition, nextItemPosition, newWatcher, newPredicateFunc); if (newFilteredIndex != null) { baseInsertItem(newFilteredIndex.Value, addedSourceItem); } _isConsistent = true; raiseConsistencyRestored(); break; case NotifyCollectionChangedAction.Remove: unregisterSourceItem(e.OldStartingIndex); break; case NotifyCollectionChangedAction.Move: _isConsistent = false; int newSourceIndex1 = e.NewStartingIndex; int oldSourceIndex = e.OldStartingIndex; if (newSourceIndex1 != oldSourceIndex) { ItemInfo itemInfoOfOldSourceIndex = _itemInfos[oldSourceIndex]; ItemInfo itemInfoOfNewSourceIndex = _itemInfos[newSourceIndex1]; Position newPosition1; Position nextPosition1; Position itemInfoOfOldSourceIndexFilteredPosition = itemInfoOfOldSourceIndex.FilteredPosition; Position itemInfoOfNewSourceIndexNextFilteredItemPosition = itemInfoOfNewSourceIndex.NextFilteredItemPosition; Position itemInfoOfNewSourceIndexFilteredPosition = itemInfoOfNewSourceIndex.FilteredPosition; if (itemInfoOfOldSourceIndexFilteredPosition != null) { int oldFilteredIndex = itemInfoOfOldSourceIndexFilteredPosition.Index; int newFilteredIndex1; newPosition1 = itemInfoOfOldSourceIndexFilteredPosition; if (itemInfoOfNewSourceIndexFilteredPosition == null) { //nextPositionIndex = itemInfoOfNewSourceIndex.NextFilteredItemIndex; nextPosition1 = itemInfoOfNewSourceIndexNextFilteredItemPosition != itemInfoOfOldSourceIndexFilteredPosition ? itemInfoOfNewSourceIndexNextFilteredItemPosition : itemInfoOfOldSourceIndex.NextFilteredItemPosition; newFilteredIndex1 = oldSourceIndex < newSourceIndex1 ? itemInfoOfNewSourceIndexNextFilteredItemPosition.Index - 1 : itemInfoOfNewSourceIndexNextFilteredItemPosition.Index; } else { nextPosition1 = oldSourceIndex < newSourceIndex1 ? itemInfoOfNewSourceIndexNextFilteredItemPosition : itemInfoOfNewSourceIndexFilteredPosition; newFilteredIndex1 = itemInfoOfNewSourceIndexFilteredPosition.Index; } _filteredPositions.Move( oldFilteredIndex, newFilteredIndex1); modifyNextFilteredItemIndex(oldSourceIndex, itemInfoOfOldSourceIndex.NextFilteredItemPosition); _sourcePositions.Move(oldSourceIndex, newSourceIndex1); itemInfoOfOldSourceIndex.NextFilteredItemPosition = nextPosition1; modifyNextFilteredItemIndex(newSourceIndex1, newPosition1); baseMoveItem(oldFilteredIndex, newFilteredIndex1); } else { nextPosition1 = oldSourceIndex < newSourceIndex1 ? itemInfoOfNewSourceIndexNextFilteredItemPosition : (itemInfoOfNewSourceIndexFilteredPosition ?? itemInfoOfNewSourceIndexNextFilteredItemPosition); itemInfoOfOldSourceIndex.NextFilteredItemPosition = nextPosition1; _sourcePositions.Move(oldSourceIndex, newSourceIndex1); } } _isConsistent = true; raiseConsistencyRestored(); break; case NotifyCollectionChangedAction.Reset: _isConsistent = false; initializeFromSource(); _isConsistent = true; raiseConsistencyRestored(); break; case NotifyCollectionChangedAction.Replace: _isConsistent = false; int sourceIndex = e.NewStartingIndex; ItemInfo replacingItemInfo = _itemInfos[sourceIndex]; ExpressionWatcher oldExpressionWatcher = replacingItemInfo.ExpressionWatcher; oldExpressionWatcher.Dispose(); ExpressionWatcher watcher; Func <bool> predicateFunc; TSourceItem replacingSourceItem = _sourceAsList[sourceIndex]; getNewExpressionWatcherAndPredicateFunc(replacingSourceItem, out watcher, out predicateFunc); replacingItemInfo.PredicateFunc = predicateFunc; watcher.ValueChanged = expressionWatcher_OnValueChanged; watcher._position = oldExpressionWatcher._position; replacingItemInfo.ExpressionWatcher = watcher; if (!processChangeSourceItem(sourceIndex) && replacingItemInfo.FilteredPosition != null) { baseSetItem(replacingItemInfo.FilteredPosition.Index, replacingSourceItem); } _isConsistent = true; raiseConsistencyRestored(); break; } _isConsistent = false; if (_deferredExpressionWatcherChangedProcessings != null) { while (_deferredExpressionWatcherChangedProcessings.Count > 0) { ExpressionWatcher.Raise expressionWatcherRaise = _deferredExpressionWatcherChangedProcessings.Dequeue(); if (!expressionWatcherRaise.ExpressionWatcher._disposed) { _handledEventSender = expressionWatcherRaise.EventSender; _handledEventArgs = expressionWatcherRaise.EventArgs; processChangeSourceItem(expressionWatcherRaise.ExpressionWatcher._position.Index); } } } _isConsistent = true; raiseConsistencyRestored(); _handledEventSender = null; _handledEventArgs = null; }
private void handleSourceCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { checkConsistent(sender, e); if (!_rootSourceWrapper && _lastProcessedSourceChangeMarker == _sourceAsList.ChangeMarkerField) { return; } _handledEventSender = sender; _handledEventArgs = e; _lastProcessedSourceChangeMarker = !_lastProcessedSourceChangeMarker; switch (e.Action) { case NotifyCollectionChangedAction.Add: _isConsistent = false; int newSourceIndex = e.NewStartingIndex; TSourceItem addedSourceItem = _sourceAsList[newSourceIndex]; ItemInfo itemInfo = registerSourceItem(addedSourceItem, newSourceIndex); if (ApplyPredicate(newSourceIndex)) { _predicatePassedCount++; itemInfo.PredicateResult = true; } calculateValue(); _isConsistent = true; raiseConsistencyRestored(); break; case NotifyCollectionChangedAction.Remove: int oldStartingIndex = e.OldStartingIndex; if (_itemInfos[oldStartingIndex].PredicateResult) { _predicatePassedCount--; } unregisterSourceItem(oldStartingIndex); calculateValue(); break; case NotifyCollectionChangedAction.Move: int newSourceIndex1 = e.NewStartingIndex; int oldSourceIndex = e.OldStartingIndex; if (newSourceIndex1 != oldSourceIndex) { _sourcePositions.Move(oldSourceIndex, newSourceIndex1); } break; case NotifyCollectionChangedAction.Reset: _isConsistent = false; initializeFromSource(); _isConsistent = true; raiseConsistencyRestored(); break; case NotifyCollectionChangedAction.Replace: _isConsistent = false; int newStartingIndex = e.NewStartingIndex; ItemInfo replacingItemInfo = _itemInfos[newStartingIndex]; ExpressionWatcher oldExpressionWatcher = replacingItemInfo.ExpressionWatcher; oldExpressionWatcher.Dispose(); if (replacingItemInfo.PredicateResult) { _predicatePassedCount--; } ExpressionWatcher watcher; Func <bool> predicateFunc; TSourceItem replacingSourceItem = _sourceAsList[newStartingIndex]; getNewExpressionWatcherAndPredicateFunc(replacingSourceItem, out watcher, out predicateFunc); replacingItemInfo.PredicateFunc = predicateFunc; watcher.ValueChanged = expressionWatcher_OnValueChanged; watcher._position = oldExpressionWatcher._position; replacingItemInfo.ExpressionWatcher = watcher; if (ApplyPredicate(newStartingIndex)) { _predicatePassedCount++; replacingItemInfo.PredicateResult = true; } else { replacingItemInfo.PredicateResult = false; } calculateValue(); _isConsistent = true; raiseConsistencyRestored(); break; } _isConsistent = false; if (_deferredExpressionWatcherChangedProcessings != null) { while (_deferredExpressionWatcherChangedProcessings.Count > 0) { ExpressionWatcher.Raise expressionWatcherRaise = _deferredExpressionWatcherChangedProcessings.Dequeue(); if (!expressionWatcherRaise.ExpressionWatcher._disposed) { _handledEventSender = expressionWatcherRaise.EventSender; _handledEventArgs = expressionWatcherRaise.EventArgs; processExpressionWatcherValueChanged(expressionWatcherRaise.ExpressionWatcher); } } } _isConsistent = true; raiseConsistencyRestored(); _handledEventSender = null; _handledEventArgs = null; }
private void handleSourceCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { checkConsistent(sender, e); if (!_rootSourceWrapper && _lastProcessedSourceChangeMarker == _sourceAsList.ChangeMarkerField) { return; } _handledEventSender = sender; _handledEventArgs = e; _lastProcessedSourceChangeMarker = !_lastProcessedSourceChangeMarker; ItemInfo itemInfo; switch (e.Action) { case NotifyCollectionChangedAction.Add: _isConsistent = false; int newStartingIndex = e.NewStartingIndex; TSourceItem addedItem = _sourceAsList[newStartingIndex]; itemInfo = registerSourceItem(addedItem, newStartingIndex); baseInsertItem(newStartingIndex, applySelector(itemInfo, addedItem)); _isConsistent = true; raiseConsistencyRestored(); break; case NotifyCollectionChangedAction.Remove: int oldStartingIndex = e.OldStartingIndex; unregisterSourceItem(oldStartingIndex); baseRemoveItem(oldStartingIndex); break; case NotifyCollectionChangedAction.Replace: _isConsistent = false; int newStartingIndex1 = e.NewStartingIndex; TSourceItem newItem = _sourceAsList[newStartingIndex1]; ItemInfo replacingItemInfo = _itemInfos[newStartingIndex1]; unregisterSourceItem(newStartingIndex1, true); itemInfo = registerSourceItem(newItem, newStartingIndex1, replacingItemInfo); baseSetItem(newStartingIndex1, applySelector(itemInfo, newItem)); _isConsistent = true; raiseConsistencyRestored(); break; case NotifyCollectionChangedAction.Move: int oldStartingIndex2 = e.OldStartingIndex; int newStartingIndex2 = e.NewStartingIndex; if (oldStartingIndex2 != newStartingIndex2) { _sourcePositions.Move(oldStartingIndex2, newStartingIndex2); baseMoveItem(oldStartingIndex2, newStartingIndex2); } break; case NotifyCollectionChangedAction.Reset: _isConsistent = false; initializeFromSource(); _isConsistent = true; raiseConsistencyRestored(); break; } _isConsistent = false; if (_deferredExpressionWatcherChangedProcessings != null) { while (_deferredExpressionWatcherChangedProcessings.Count > 0) { ExpressionWatcher.Raise expressionWatcherRaise = _deferredExpressionWatcherChangedProcessings.Dequeue(); if (!expressionWatcherRaise.ExpressionWatcher._disposed) { _handledEventSender = expressionWatcherRaise.EventSender; _handledEventArgs = expressionWatcherRaise.EventArgs; processExpressionWatcherValueChanged(expressionWatcherRaise.ExpressionWatcher); } } } _isConsistent = true; raiseConsistencyRestored(); _handledEventSender = null; _handledEventArgs = null; }