ObservableCollection : calling OnCollectionChanged with multiple new items

前端 未结 4 1271
[愿得一人]
[愿得一人] 2020-12-06 02:33

please note that I am trying to use NotifyCollectionChangedAction.Add action instead of .Reset. the latter does work, but it is not very efficient with large collections.

4条回答
  •  天涯浪人
    2020-12-06 02:46

    you can implement AddRange() for the ObservableCollection like this as shown here:

    public class RangeObservableCollection : ObservableCollection
    {
        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 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));
        }
    }
    

    UPDATE: After binding to ListBox I was seeing an InvalidOperationException too (same message you were seeing). According to this article that's because CollectionView doesn't support range actions. Luckily the article also supplies a solution (although it feels a little "hack-ish").

    UPDATE 2: Added a fix that raises the overridden CollectionChanged event in the overridden implementation of OnCollectionChanged().

提交回复
热议问题