Adding a contents of a List to ObservableCollection

Answered Adding a contents of a List to ObservableCollection

  • 1 мая 2012 г. 18:10
     
      С кодом

    Hi,

    I want to add the contents of a List to an ObservableCollection and have found the follow implementation of an AddRange to do this:

    public static class Extensions
    {
       public static void AddRange<T>(this ObservableCollection<T> observableCollection, IList<T> list)
       {
           foreach(var item in list)
               observableCollection.Add(item);
       }
    }

    And I call the method like below where observableCollection is a defined as ObservableCollection<string> and list is a List<string>...

    observableCollection.AddRange(list);

    This actually works fine and ultimately does what I need.  However, my problem is that the CollectionChanged event of the ObservableCollection gets fired with the addition of a new item in the AddRange implmentation.

    Is there any way to Add a List of items to an ObservableCollection whereby the CollectionChanged event will only be fired once with e.NewItems containing all the new items.  (instead of the event firing each time with e.NewItems containing one item)

    Thanks for your help on this.

Все ответы

  • 1 мая 2012 г. 18:13
     
     
  • 1 мая 2012 г. 18:25
     
     

    Hi, thanks for your quick response.

    I don't think this is what I need as I still want the CollectionChanged event to fire at the end of adding all the items to the ObservableCollection (e.g. say the list has 100 items I want the CollectionChanged event to fire after 100 items have been added to the collection and not after each individual one is added).

    If I am to use the boolean flag then it just stops me from processing the items added to the collection as I the flag is always set to say the collection is being updated until after all the items have been added at which point all the CollectionChanged events have been fired.

    Ideally, I'm hoping there is a better implementation of my AddRange method?  Something that will enable me to add all the items from the List before firing the CollectionChanged event?

    Thanks

  • 1 мая 2012 г. 20:11
     
     

    Hi,

    Maybe you can explain a little more clearly what it is you want to do. Because it sounds to me like all you need to do is this is to modify your add range method so that it gets the count of the collection being added

    then have an if so on one the last item to be added you set the flag to true (so the collection event can execute) then add in your last item

  • 2 мая 2012 г. 10:41
     
     Отвечено С кодом

    Hi Pritesh,

    I found a solution to my problem using a range of other blogs, etc...  Below is the code for my solution and some of the links for the forums/discussions that I visited...  There was no one solution that really hit the nail on the head but anybody having the same problem can use the code block below and visit the sites to get an understanding of what is needed.

    The implementation of the AddRange method is just one part of the problem.  After this is done, the problem then becomes that CollectionView objects do not support Range operations so you must supress the CollectionChanged event until all items are added to the list.

    Thanks for your help and suggestions on this topic.

    public class RangeObservableCollection<T> : ObservableCollection<T>
    {
        private bool _suppressNotification;
        public override event NotifyCollectionChangedEventHandler CollectionChanged;
        protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
        {
            if (!_suppressNotification)
                base.OnCollectionChanged(e);
        }
        protected virtual void OnCollectionChangedMultiItem(NotifyCollectionChangedEventArgs e)
        {
            NotifyCollectionChangedEventHandler handlers = CollectionChanged;
            if (handlers != null)
            {
                foreach (NotifyCollectionChangedEventHandler handler in handlers.GetInvocationList())
                {
                    if (handler.Target is CollectionView)
                        ((CollectionView)handler.Target).Refresh();
                    else
                        handler(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;
                
            NotifyCollectionChangedEventArgs obEvtArgs = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add,
                list as System.Collections.IList);
            OnCollectionChangedMultiItem(obEvtArgs);
        }
    }

    Link1: http://geekswithblogs.net/NewThingsILearned/archive/2008/01/16/listcollectionviewcollectionview-doesnt-support-notifycollectionchanged-with-multiple-items.aspx

    Link2: http://peteohanlon.wordpress.com/2008/10/22/bulk-loading-in-observablecollection/

    Link3: http://stackoverflow.com/questions/57020/which-net-collection-for-adding-multiple-objects-at-once-and-getting-notified

    Link4: http://stackoverflow.com/questions/3300845/observablecollection-calling-oncollectionchanged-with-multiple-new-items

  • 3 мая 2012 г. 5:29
    Модератор
     
     

    Hi wallaceoc,

    Thank you for sharing your solution here.

    Best regards,


    Sheldon _Xiao[MSFT]
    MSDN Community Support | Feedback to us
    Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.