I would like my own descendant of ObservableCollection
to support AddRange
method.
Here is what I currently have:
public class ObservableCollectionPlus<T> : ObservableCollection<T>
{
public void InsertRange(IEnumerable<T> items)
{
this.CheckReentrancy();
foreach (var item in items) Items.Add(item);
var type = NotifyCollectionChangedAction.Reset;
var colChanged = new NotifyCollectionChangedEventArgs(type);
var countChanged = new PropertyChangedEventArgs("Count");
OnPropertyChanged(countChanged);
OnCollectionChanged(colChanged);
}
}
I don't have much knowledge of what's exactly going on here and why are these events get raised. This is a solutiom that I've assembled after doing some research on google and stackoverflow.
Now, if I bind an instance of my class to say LongListSelector
then, after dynamically adding items via InsertRange
to ObservableCollectionPlus
, a binded LongListSelector
's scroll position is sent to it's top.
If I add items in this standard way: foreach (var item in items) collection.Add(item);
then LongListSelector
's position does not get shifted. But of course this way I get DataBinding notifications overhead in which is undesired.
Apparently, something is done wrong in my current solution. How can I implement InsertRange
that will behave exactly like foreach (var item in items) collection.Add(item);
but will only fire DataBinding notification once and will not do strange things to binded object's scroll position?
It could be because your sending the NotifyCollectionChangedAction.Reset
notification, maybe just the NotifyCollectionChangedAction.Add
will work, Maybe :)
public class ObservableRangeCollection<T> : ObservableCollection<T>
{
public void AddRange(IEnumerable<T> collection)
{
foreach (var i in collection)
{
Items.Add(i);
}
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, collection.ToList()));
}
}