обратите внимание на то, что я пытаюсь использовать NotifyCollectionChangedAction. Добавьте действие вместо.Reset., последний работает, но это не очень эффективно с большим количеством.
таким образом, я разделил ObservableCollection на подклассы:
public class SuspendableObservableCollection<T> : ObservableCollection<T>
по некоторым причинам, этот код:
private List<T> _cachedItems;
...
public void FlushCache() {
if (_cachedItems.Count > 0) {
foreach (var item in _cachedItems)
Items.Add(item);
OnCollectionChanged(new NotifyCollectionChangedEventArgs(
NotifyCollectionChangedAction.Add, (IList<T>)_cachedItems));
}
}
бросает событие Add набора, относится к объекту, который не принадлежит набору
это, кажется, ошибка в BCL?
Я могу ступить через и видеть до вызова OnCollectionChanged, что новые объекты добавляются к этому. Объекты
WOW
просто сделанный колеблющимся исследованием. Ни один из этих подходов не работал на меня (сброс, addrange), потому что ошибка, кажется, инициирована, ТОЛЬКО ЕСЛИ этот набор связывается с моим Listview!!
TestObservableCollection<Trade> testCollection = new TestObservableCollection<Trade>();
List<Trade> testTrades = new List<Trade>();
for (int i = 0; i < 200000; i++)
testTrades.Add(t);
testCollection.AddRange(testTrades); // no problems here..
_trades.AddRange(testTrades); // this one is bound to ListView .. BOOOM!!!
В заключение ObservableCollection действительно поддерживает добавляющие возрастающие списки, но ListView не делает. Andyp выяснил обходное решение, чтобы заставить его работать с CollectionView ниже, но так как.Refresh () назван, который не отличается, чем просто вызов OnCollectionChanged (.Reset)..
вы можете реализовать AddRange () для ObservableCollection, как показано здесь :
public class RangeObservableCollection<T> : ObservableCollection<T>
{
private bool _SuppressNotification;
public override event NotifyCollectionChangedEventHandler CollectionChanged;
protected virtual void OnCollectionChangedMultiItem(
NotifyCollectionChangedEventArgs e)
{
NotifyCollectionChangedEventHandler handlers = this.CollectionChanged;
if (handlers != null)
{
foreach (NotifyCollectionChangedEventHandler handler in
handlers.GetInvocationList())
{
if (handler.Target is CollectionView)
((CollectionView)handler.Target).Refresh();
else
handler(this, e);
}
}
}
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
if (!_SuppressNotification)
{
base.OnCollectionChanged(e);
if (CollectionChanged != null)
CollectionChanged.Invoke(this, e);
}
}
public void AddRange(IEnumerable<T> list)
{
if (list == null)
throw new ArgumentNullException("list");
_SuppressNotification = true;
foreach (T item in list)
{
Add(item);
}
_SuppressNotification = false;
OnCollectionChangedMultiItem(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, list));
}
}
ОБНОВЛЕНИЕ: после привязки к ListBox я тоже видел исключение InvalidOperationException (такое же сообщение вы видели). Согласно этой статье это потому, что CollectionView не поддерживает действия с диапазоном.К счастью, статья также предлагает решение (хотя это кажется немного "взломанным").
ОБНОВЛЕНИЕ 2: добавлено исправление, которое вызывает переопределенное событие CollectionChanged в переопределенной реализации OnCollectionChanged ().
Я полагаю, что вам нужно привести его к IList
:
base.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction. Add, (IList)_cachedItems));