/// <summary> /// Construtor padrão. /// </summary> /// <param name="source">Relação da coleção de origem dos dados.</param> /// <param name="comparer">Comparador que será utilizado para ordenar os itens.</param> public SortableObservableCollection(IObservableCollection <T> source, IComparer <T> comparer) { source.Require("source").NotNull(); comparer.Require("comparer").NotNull(); _source = source; _comparer = comparer; _comparerPropertiesContainer = comparer as IPropertiesContainer; _source.CollectionChanged += SourceCollectionChanged; _indexes = new BaseObservableCollection <int>(); for (var i = 0; i < _source.Count; i++) { _indexes.Add(i); } foreach (var i in _source) { RegisterItem(i); } CalculateIndexes(); }
/// <summary> /// Método acionado quando a coleção de origem for alterada. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void SourceCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { if (e.Action == NotifyCollectionChangedAction.Add) { for (var i = 0; i < e.NewItems.Count; i++) { var item = (T)e.NewItems[i]; var inserted = false; for (var j = 0; j < _indexes.Count; j++) { if (_comparer.Compare(_source[_indexes[j]], item) > 0) { _indexes.Insert(j, e.NewStartingIndex + i); RegisterItem(item); inserted = true; break; } } if (!inserted) { _indexes.Add(e.NewStartingIndex + i); } } } else if (e.Action == NotifyCollectionChangedAction.Move) { for (var i = 0; i < e.NewItems.Count; i++) { var newIndex = -1; var oldIndex = -1; for (var j = 0; (newIndex < 0 || oldIndex < 0) && j < _indexes.Count; j++) { if (newIndex < 0 && _indexes[j] == e.NewStartingIndex + i) { newIndex = j; } else if (oldIndex < 0 && _indexes[j] == e.OldStartingIndex + i) { oldIndex = j; } } if (newIndex >= 0 && oldIndex >= 0) { var aux = _indexes[newIndex]; _indexes[newIndex] = _indexes[oldIndex]; _indexes[oldIndex] = aux; } } } else if (e.Action == NotifyCollectionChangedAction.Remove) { for (var i = 0; i < e.OldItems.Count; i++) { for (var j = 0; j < _indexes.Count; j++) { if (_indexes[j] == e.OldStartingIndex + i) { UnregisterItem((T)e.OldItems[i]); _indexes.CollectionChanged -= IndexesCollectionChanged; _indexes.Clear(); for (var x = 0; x < _source.Count; x++) { _indexes.Add(x); } try { CalculateIndexesWithoutNotifyChanges(); } finally { _indexes.CollectionChanged += IndexesCollectionChanged; } if (CollectionChanged != null) { CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, e.OldItems[i], j)); } break; } } } } else if (e.Action == NotifyCollectionChangedAction.Replace) { CalculateIndexes(); } else if (e.Action == NotifyCollectionChangedAction.Reset) { try { _indexes.CollectionChanged -= IndexesCollectionChanged; foreach (var item in _source) { UnregisterItem(item); } for (var i = 0; i < _source.Count; i++) { _indexes.Add(i); } } finally { _indexes.CollectionChanged += IndexesCollectionChanged; } CalculateIndexes(); } }