我想做的是FreezableCollection.AddRange(collectionToAdd)

本文关键字:AddRange collectionToAdd FreezableCollection | 更新日期: 2023-09-27 18:28:58

我想做的是FreezableCollection.AddRange(collectionToAdd)

每次我添加到FreezableCollection时,都会引发一个事件并发生一些事情。现在我有一个新的集合想要添加,但这次我希望FreezableCollection的CollectionChanged事件只触发一次。

循环并添加它们将引发每个新项目的事件。

有没有一种方法可以像List.AddRange一样,一次性添加到FreezableCollection?

我想做的是FreezableCollection.AddRange(collectionToAdd)

从集合派生并覆盖要更改的行为。我可以这样做:

public class PrestoObservableCollection<T> : ObservableCollection<T>
    {
        private bool _delayOnCollectionChangedNotification { get; set; }
        /// <summary>
        /// Add a range of IEnumerable items to the observable collection and optionally delay notification until the operation is complete.
        /// </summary>
        /// <param name="itemsToAdd"></param>
        public void AddRange(IEnumerable<T> itemsToAdd)
        {
            if (itemsToAdd == null) throw new ArgumentNullException("itemsToAdd");
            if (itemsToAdd.Any() == false) { return; }  // Nothing to add.
            _delayOnCollectionChangedNotification = true;            
            try
            {
                foreach (T item in itemsToAdd) { this.Add(item); }
            }
            finally
            {
                ResetNotificationAndFireChangedEvent();
            }
        }
        /// <summary>
        /// Clear the items in the ObservableCollection and optionally delay notification until the operation is complete.
        /// </summary>
        public void ClearItemsAndNotifyChangeOnlyWhenDone()
        {
            try
            {
                if (!this.Any()) { return; }  // Nothing available to remove.
                _delayOnCollectionChangedNotification = true;
                this.Clear();
            }
            finally
            {
                ResetNotificationAndFireChangedEvent();
            }
        }
        /// <summary>
        /// Override the virtual OnCollectionChanged() method on the ObservableCollection class.
        /// </summary>
        /// <param name="e">Event arguments</param>
        protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
        {
            if (_delayOnCollectionChangedNotification) { return; }
            base.OnCollectionChanged(e);
        }
        private void ResetNotificationAndFireChangedEvent()
        {
            // Turn delay notification off and call the OnCollectionChanged() method and tell it we had a change in the collection.
            _delayOnCollectionChangedNotification = false;
            this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
        }
    }

为了跟进@BobHorn的好答案,使其与FreezableCollection、一起工作

来自文档:

此成员是一个显式接口成员实现。可以是仅当FreezableCollection实例强制转换为INotifyCollectionChanged接口。

所以你可以用石膏来做。

(FreezableCollection as INotifyCollectionChanged).CollectionChanged += OnCollectionChanged;