251

What is the use of ObservableCollection in .net?

santosh singh
  • 27,666
  • 26
  • 83
  • 129

8 Answers8

252

ObservableCollection is a collection that allows code outside the collection be aware of when changes to the collection (add, move, remove) occur. It is used heavily in WPF and Silverlight but its use is not limited to there. Code can add event handlers to see when the collection has changed and then react through the event handler to do some additional processing. This may be changing a UI or performing some other operation.

The code below doesn't really do anything but demonstrates how you'd attach a handler in a class and then use the event args to react in some way to the changes. WPF already has many operations like refreshing the UI built in so you get them for free when using ObservableCollections

class Handler
{
    private ObservableCollection<string> collection;

    public Handler()
    {
        collection = new ObservableCollection<string>();
        collection.CollectionChanged += HandleChange;
    }

    private void HandleChange(object sender, NotifyCollectionChangedEventArgs e)
    {
        foreach (var x in e.NewItems)
        {
            // do something
        }

        foreach (var y in e.OldItems)
        {
            //do something
        }
        if (e.Action == NotifyCollectionChangedAction.Move)
        {
            //do something
        }
    }
}
Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
Craig Suchanec
  • 10,474
  • 3
  • 31
  • 39
  • 24
    `e.NewItems` & `e.OldsItems` may be null depending on the action. It may throw `NullReferenceException`. – dovid Jan 11 '15 at 11:55
  • 8
    sidenote: when Action is Move, the moved element will appear in both NewItems and OldItems – bohdan_trotsenko Mar 14 '15 at 16:48
  • Thank you for this: > WPF already has many operations like refreshing the UI built in so you get them for free when using ObservableCollections – SlowLearner Jun 05 '18 at 12:06
169

An ObservableCollection works essentially like a regular collection except that it implements the interfaces:

As such it is very useful when you want to know when the collection has changed. An event is triggered that will tell the user what entries have been added/removed or moved.

More importantly they are very useful when using databinding on a form.

Bakudan
  • 19,134
  • 9
  • 53
  • 73
Liz
  • 8,780
  • 2
  • 36
  • 40
62

From Pro C# 5.0 and the .NET 4.5 Framework

The ObservableCollection<T> class is very useful in that it has the ability to inform external objects when its contents have changed in some way (as you might guess, working with ReadOnlyObservableCollection<T> is very similar, but read-only in nature). In many ways, working with the ObservableCollection<T> is identical to working with List<T>, given that both of these classes implement the same core interfaces. What makes the ObservableCollection<T> class unique is that this class supports an event named CollectionChanged. This event will fire whenever a new item is inserted, a current item is removed (or relocated), or if the entire collection is modified. Like any event, CollectionChanged is defined in terms of a delegate, which in this case is NotifyCollectionChangedEventHandler. This delegate can call any method that takes an object as the first parameter, and a NotifyCollectionChangedEventArgs as the second. Consider the following Main() method, which populates an observable collection containing Person objects and wires up the CollectionChanged event:

class Program
{
   static void Main(string[] args)
   {
     // Make a collection to observe and add a few Person objects.
     ObservableCollection<Person> people = new ObservableCollection<Person>()
     {
        new Person{ FirstName = "Peter", LastName = "Murphy", Age = 52 },
        new Person{ FirstName = "Kevin", LastName = "Key", Age = 48 },
     };
     // Wire up the CollectionChanged event.
     people.CollectionChanged += people_CollectionChanged;
     // Now add a new item.
     people.Add(new Person("Fred", "Smith", 32));

     // Remove an item.
     people.RemoveAt(0);

     Console.ReadLine();
   }
   static void people_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
   {
       // What was the action that caused the event?
        Console.WriteLine("Action for this event: {0}", e.Action);

        // They removed something. 
        if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove)
        {
            Console.WriteLine("Here are the OLD items:");
            foreach (Person p in e.OldItems)
            {
                Console.WriteLine(p.ToString());
            }
            Console.WriteLine();
        }

        // They added something. 
        if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add)
        {
            // Now show the NEW items that were inserted.
            Console.WriteLine("Here are the NEW items:");
            foreach (Person p in e.NewItems)
            {
                Console.WriteLine(p.ToString());
            }
        }
   }
}

The incoming NotifyCollectionChangedEventArgs parameter defines two important properties, OldItems and NewItems, which will give you a list of items that were currently in the collection before the event fired, and the new items that were involved in the change. However, you will want to examine these lists only under the correct circumstances. Recall that the CollectionChanged event can fire when items are added, removed, relocated, or reset. To discover which of these actions triggered the event, you can use the Action property of NotifyCollectionChangedEventArgs. The Action property can be tested against any of the following members of the NotifyCollectionChangedAction enumeration:

public enum NotifyCollectionChangedAction
{
Add = 0,
Remove = 1,
Replace = 2,
Move = 3,
Reset = 4,
}

Members of System.Collections.ObjectModel

x19
  • 8,277
  • 15
  • 68
  • 126
  • 2
    will the people_CollectionChanged event fire if i change the name of a Person in the in the collection (without altering the collection itself?) – BenKoshy Mar 01 '18 at 00:41
  • It should fall into the ```NotifyCollectionChangedAction.Replace``` bucket, as the new value replaces the old value (unless, we reset the values to their defaults in the modification attempted). Although, I would be curious to know more about or what you referred to, by: "modifying an item in the collection without altering the collection itself"? Did you mean via an iterator, perhaps? – Abhay Nagaraj Nov 02 '20 at 17:12
  • 2
    Changing any Property or Field of the Observed Collection will not trigger CollectionChanged. – BillW May 15 '21 at 00:37
34

Explanation without Code

For those wanting an answer without any code behind it (boom-tish) with a story (to help you remember):

Normal Collections - No Notifications

Every now and then I go to NYC and my wife asks me to buy stuff. So I take a shopping list with me. The list has a lot of things on there like:

  1. Louis Vuitton handbag ($5000)
  2. Clive Christian’s Imperial Majesty Perfume ($215,000 )
  3. Gucci Sunglasses ($2000)

hahaha well I"m not buying that stuff. So I cross them off and remove them from the list and I add instead:

  1. 12 dozen Titleist golf balls.
  2. 12 lb bowling ball.

So I usually come home without the goods and she's never pisssssssed off the thing is that she doesn't know about what i take off the list and what I add onto it; she gets no notifications.

The ObservableCollection - notifications when changes made

Now, whenever I remove something from the list: she get's a notification.

The observable collection works just the same way. If you add or remove something to or from it: someone is notified.

And when they are notified, then bunker down or run for cover! Of course, the consequences are customisable via an event handler.

Silly story, but hopefully you'll remember the concept now.

BenKoshy
  • 33,477
  • 14
  • 111
  • 80
7

One of the biggest uses is that you can bind UI components to one, and they'll respond appropriately if the collection's contents change. For example, if you bind a ListView's ItemsSource to one, the ListView's contents will automatically update if you modify the collection.

EDIT: Here's some sample code from MSDN: http://msdn.microsoft.com/en-us/library/ms748365.aspx

In C#, hooking the ListBox to the collection could be as easy as

listBox.ItemsSource = NameListData;

though if you haven't hooked the list up as a static resource and defined NameItemTemplate you may want to override PersonName's ToString(). For example:

public override ToString()
{
    return string.Format("{0} {1}", this.FirstName, this.LastName);
}
Sean U
  • 6,730
  • 1
  • 24
  • 43
6

it is a collection which is used to notify mostly UI to change in the collection , it supports automatic notification.

Mainly used in WPF ,

Where say suppose you have UI with a list box and add button and when you click on he button an object of type suppose person will be added to the obseravablecollection and you bind this collection to the ItemSource of Listbox , so as soon as you added a new item in the collection , Listbox will update itself and add one more item in it.

TalentTuner
  • 17,262
  • 5
  • 38
  • 63
5
class FooObservableCollection : ObservableCollection<Foo>
{
    protected override void InsertItem(int index, Foo item)
    {
        base.Add(index, Foo);

        if (this.CollectionChanged != null)
            this.CollectionChanged(this, new NotifyCollectionChangedEventArgs (NotifyCollectionChangedAction.Add, item, index);
    }
}

var collection = new FooObservableCollection();
collection.CollectionChanged += CollectionChanged;

collection.Add(new Foo());

void CollectionChanged (object sender, NotifyCollectionChangedEventArgs e)
{
    Foo newItem = e.NewItems.OfType<Foo>().First();
}
abatishchev
  • 98,240
  • 88
  • 296
  • 433
  • can you explain why FooObservableCollection implemented collection? And why you ovverided InsertItem ? – Arie Nov 21 '18 at 12:56
  • @Arie: honestly, 8 years later I don't remember, so no idea. From what I see [in the docs](https://learn.microsoft.com/en-us/dotnet/api/system.collections.objectmodel.observablecollection-1?view=netframework-4.7.2#events) there is no need for any of this, it all should come out of the box. – abatishchev Nov 26 '18 at 01:48
0

ObservableCollection Caveat

Mentioned above (Said Roohullah Allem)

What makes the ObservableCollection class unique is that this class supports an event named CollectionChanged.

Keep this in mind...If you adding a large number of items to an ObservableCollection the UI will also update that many times. This can really gum up or freeze your UI. A work around would be to create a new list, add all the items then set your property to the new list. This hits the UI once. Again...this is for adding a large number of items.

Chris Catignani
  • 5,040
  • 16
  • 42
  • 49