I have an ObservableCollection
of items that is bound to a list control in my view.
I have a situation where I need to add a chunk of values to the start of the collection.
Collection<T>.Insert
documentation specifies each insert as an O(n) operation, and each insert also generates a CollectionChanged
notification.
Therefore I would ideally like to insert the whole range of items in one move, meaning only one shuffle of the underlying list, and hopefully one CollectionChanged
notification (presumably a "reset").
Collection<T>
does not expose any method for doing this. List<T>
has InsertRange()
, but IList<T>
, that Collection<T>
exposes via its Items
property does not.
Is there any way at all to do this?
The ObservableCollection exposes an protected Items
property which is the underlying collection without the notification semantics. This means you can build a collection that does what you want by inheriting ObservableCollection:
class RangeEnabledObservableCollection<T> : ObservableCollection<T>
{
public void InsertRange(IEnumerable<T> items)
{
this.CheckReentrancy();
foreach(var item in items)
this.Items.Add(item);
this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
}
Usage:
void Main()
{
var collection = new RangeEnabledObservableCollection<int>();
collection.CollectionChanged += (s,e) => Console.WriteLine("Collection changed");
collection.InsertRange(Enumerable.Range(0,100));
Console.WriteLine("Collection contains {0} items.", collection.Count);
}