260

I want to know the difference between ObservableCollection and BindingList because I've used both to notify for any add/delete change in Source, but I actually do not know when to prefer one over the other.

Why would I choose one of the following over the other?

ObservableCollection<Employee> lstEmp = new ObservableCollection<Employee>();

or

BindingList<Employee> lstEmp = new BindingList<Employee>();
Olivier Jacot-Descombes
  • 104,806
  • 13
  • 138
  • 188
Azhar
  • 20,500
  • 38
  • 146
  • 211

5 Answers5

304

An ObservableCollection can be updated from UI exactly like any collection. The true difference is rather straightforward:

ObservableCollection<T> implements INotifyCollectionChanged which provides notification when the collection is changed (you guessed ^^) It allows the binding engine to update the UI when the ObservableCollection is updated.

However, BindingList<T> implements IBindingList.

IBindingList provides notification on collection changes, but not only that. It provides a whole bunch of functionality which can be used by the UI to provide a lot more things than only UI updates according to changes, like:

  • Sorting
  • Searching
  • Add through factory (AddNew member function).
  • Readonly list (CanEdit property)

All these functionalities are not available in ObservableCollection<T>

Another difference is that BindingList relays item change notifications when its items implement INotifyPropertyChanged. If an item raises a PropertyChanged event, the BindingList will receive it an raises a ListChangedEvent with ListChangedType.ItemChanged and OldIndex=NewIndex (if an item was replaced, OldIndex=-1). ObservableCollection doesn't relay item notifications.

Note that in Silverlight, BindingList is not available as an option: You can however use ObservableCollections and ICollectionView (and IPagedCollectionView if I remember well).

Rudi Visser
  • 21,350
  • 5
  • 71
  • 97
Eilistraee
  • 8,220
  • 1
  • 27
  • 30
  • 8
    Another thing to consider is performance, see: http://www.themissingdocs.net/wordpress/?p=465 – Jarek Mazur Apr 16 '15 at 12:07
  • 2
    Thank you, I wasn't aware of the actual implementation of BindingList. I tend to use ObservableCollection and ICollectionView – Eilistraee Apr 17 '15 at 14:11
  • 8
    While the information in this answer is correct, any WPF users should beware: BindingList doesn't implement INotifyCollectionChanged and will cause a memory leak if bound to a control's ItemsSource property. ObservableCollection does implement the interface and won't cause any such leaks. – Brandon Hood Apr 05 '17 at 17:03
  • 1
    If BindingList implements sorting, then why can't you sort a grid bound to a BindingList? – Robert Harvey Mar 01 '18 at 16:36
  • Is `BindingList` obsolete? – Shimmy Weitzhandler Oct 27 '19 at 04:18
29

The practical difference is that BindingList is for WinForms, and ObservableCollection is for WPF.

From a WPF perspective, BindingList isnt properly supported, and you would never really use it in a WPF project unless you really had to.

Dean Chalk
  • 20,076
  • 6
  • 59
  • 90
  • 1
    Interesting. As a Silverlight Dev, I didn't know that. Thanks. And if you want sorting and filtering, ICollectionView implementations are your friend ^^ – Eilistraee Nov 26 '10 at 12:33
  • 33
    Why is it "Not supported"? ViewManager (internal) is within the PresentationFramework assembly and that supports it. Bind it to an ItemsControl for example and the change notifications are respected (i.e. items are added and removed). If it were WinForms specific should it not be better placed in the Forms namespace? – David Kiff Feb 07 '12 at 22:21
  • 7
    Agreed with David, it's in the System.Collections namespace so it should be fully supported by WPF. WPF is just a different way of UI layout. – Justin Aug 21 '12 at 19:02
  • 15
    Agree with David also, I use BindingList frequently in WPF because ObservableCollection won't bubble up property change notifications from its items. – amnesia Nov 14 '13 at 20:59
  • 5
    To give an example for "not supportet": I just found a memory leak in my WPF application that is caused by some BindingLists not implementing INotifyCollectionChanged – Breeze Nov 13 '15 at 10:20
  • I swear this needs to be in official documentation somewhere. I learned this the hard way refactoring a WinForms application (almost exclusively a WPF/XAML developer in .NET), and pretty much every third party control in WinForms would throw up when binding to an ObservableCollection with seemingly no explanation. – NimbusHex Feb 19 '20 at 01:50
14

The most important differences such as features and change notifications about the contained elements are already mentioned by the accepted answer but there are more, which also worth mentioning:

Performance

When AddNew is called, BindingList<T> searches for the added item by an IndexOf lookup. And if T implements INotifyPropertyChanged the index of a changed element is also searched by IndexOf (though there is no new lookup as long as the same item changes repeatedly). If you store thousands of elements in the collection, then ObservableCollection<T> (or a custom IBindingList implementation with O(1) lookup cost) can be more preferable.

Completeness

  • The IBindingList interface is a huge one (maybe not the cleanest design) and allows the implementors to implement only a subset of its features. For example, the AllowNew, SupportsSorting and SupportsSearching properties tell whether AddNew, ApplySort and Find methods can be used, respectively. It often surprises people that BindingList<T> itself does not support sorting. Actually it provides some virtual methods letting the derived classes add the missing features. The DataView class is an example for a full IBindingList implementation; however, it is not for typed collections in the first place. And the BindingSource class in WinForms is a hybrid example: it supports sorting if it wraps another IBindingList implementation, which supports sorting.

  • ObservableCollection<T> is already a complete implementation of the INotifyCollectionChanged interface (which has only a single event). It also has virtual members but ObservableCollection<T> is typically derived for the same reason as its base Collection<T> class: for customizing add/remove items (eg. in a data model collection) rather than adjusting binding features.

Copy vs. wrapping

Both ObservableCollection<T> and BindingList<T> have a constructor, which accepts an already existing list. Though they behave differently when they are instantiated by another collection:

  • BindingList<T> acts as an observable wrapper for the provided list, and the changes performed on the BindingList<T> will be reflected on the underlying collection as well.
  • ObservableCollection<T> on the other hand passes a new List<T> instance to the base Collection<T> constructor and copies the elements of the original collection into this new list. Of course, if T is a reference type changes on the elements will be visible from the original collection but the collection itself will not be updated.
György Kőszeg
  • 17,093
  • 6
  • 37
  • 65
  • Good and thorough answer. Just to note: `BindingList` has the perf penalty only because it is doing something extra that `ObservableCollection` doesn't support as a feature. Make the latter implement change notification of inner items and give the `changedItem`'s index, it would incur the same. I just think it was a mistake of `BindingList` part to return index in this case. They could have just returned the changed item, and left to the clients to decide if they want the item index (clients could just do a `list.IndexOf` themselves – nawfal Aug 08 '20 at 08:52
  • Good point about the wrapping vs copying behaviour difference. I always thought it would have been better to name them `ObservableList` (acts just a like any other new List) and `BindingCollection` (acts as a wrapper as other collections like Collection, ReadOnlyCollection etc). – nawfal Aug 08 '20 at 08:54
  • Thank you for your thoughts. Actually I made my libraries freely available since posting this answer, which contains a [`FastBindingList`](https://docs.kgysoft.net/corelibraries/?topic=html/T_KGySoft_ComponentModel_FastBindingList_1.htm) without the performance penalty, as well as a `SortableBindingList` and an [ObservableBindingList](https://docs.kgysoft.net/corelibraries/?topic=html/T_KGySoft_ComponentModel_ObservableBindingList_1.htm), which unifies the two worlds. GitHub: https://github.com/koszeggy/KGySoft.CoreLibraries – György Kőszeg Aug 13 '20 at 17:59
  • I looked at it, FastBindingCollection. So you are building an index map upfront. So the trade-off is elsewhere :) – nawfal Aug 15 '20 at 01:33
  • 1
    If you call a dictionary initialization trade-off, then yes, it is. :) It has a one-time O(n) cost (when you pass an already existing collection to the ctor), and a practically O(1) maintenance cost when you add/remove items. – György Kőszeg Aug 15 '20 at 09:40
3

One More big difference between ObservableCollection and BindingList that comes handy, and can be a bid decision factor on the topic :

BindingList List Change Handler:

BindingList List Change

ObservableCollection Collection change:

ObervableCollection Collection Changed

Brief of Above: If a property of an item is changed in BindingList, the ListChanged event will give you complete details of property(in PropertyDescriptor) and ObservableCollection won't give you that. In fact ObservableCollection will not raise change event for a property changed in an item.

Above conclusion are in regards of INotifyPropertyChanged implemented in model classes. By default none raises the changed event if a property is changed in an item.

Kylo Ren
  • 8,551
  • 6
  • 41
  • 66
0

Both have advantages and drawbacks that take some time to discover.

I had some trouble with BindingList because the change notification event occurs only after an item has been removed and provides only an index (which means that you have to keep track of which object was at which location if you have implement some post-removal mechanism). ObservableCollection, on the other hand, gives you a list of the removed items.

BindingList has a handy AddNew() method that allows a derived class to implement a factory pattern, e.g. to initialize the new items with values depending on the parent collection (for instance, a foreign key to the parent if the collection contains child items).

Note also that it is very easy to get a BindingList from an ObservableCollection, using (ToBindingList extension in Entity Framework), and that the returned (derived) BindingList implements features, like sorting, that lack in the plain vanilla one.