ObservableCollection: вызов OnCollectionChanged с несколькими новыми объектами

обратите внимание на то, что я пытаюсь использовать 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)..

10
задан Sonic Soul 22 July 2010 в 02:36
поделиться

2 ответа

вы можете реализовать 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 ().

7
ответ дан 4 December 2019 в 02:25
поделиться

Я полагаю, что вам нужно привести его к IList:

base.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction. Add, (IList)_cachedItems));

-1
ответ дан 4 December 2019 в 02:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: