ObservableCollection
BindingList
C# Collections
Data Binding
.NET Framework

Difference between ObservableCollection and BindingList

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

ObservableCollection<T> and BindingList<T> both support data binding, but they come from different UI eras and notify changes in different ways. The short version is that ObservableCollection<T> fits WPF-style INotifyCollectionChanged scenarios, while BindingList<T> is better aligned with WinForms and IBindingList behavior.

ObservableCollection<T>

ObservableCollection<T> lives in System.Collections.ObjectModel. It raises collection change notifications through INotifyCollectionChanged and also raises property notifications for collection-level properties such as Count.

Typical WPF example:

csharp
1using System.Collections.ObjectModel;
2
3public class ViewModel
4{
5    public ObservableCollection<string> Tasks { get; } =
6        new ObservableCollection<string>();
7}

When you add or remove items, WPF controls such as ListBox or DataGrid can refresh automatically because they understand collection-changed events.

BindingList<T>

BindingList<T> lives in System.ComponentModel. It was designed for component-style binding scenarios, especially WinForms. It exposes ListChanged events and works well with controls such as DataGridView.

csharp
1using System.ComponentModel;
2
3public class FormModel
4{
5    public BindingList<string> Tasks { get; } =
6        new BindingList<string>();
7}

WinForms data-binding infrastructure has long been built around IBindingList and related component model interfaces, so BindingList<T> often integrates more naturally there.

The Biggest Behavioral Difference

The most important difference is not "both notify changes." It is how they notify changes and what surrounding UI technology expects.

ObservableCollection<T>:

  • raises CollectionChanged
  • is the natural fit for WPF, UWP, and similar XAML-style binding systems
  • focuses on add, remove, move, replace, and reset operations

BindingList<T>:

  • raises ListChanged
  • is the natural fit for WinForms binding
  • includes concepts that work well with editable business objects and component-model binding

If your UI framework expects one notification model, using the other collection type may still work in some cases, but often with more friction.

Item Property Changes

This is where confusion often starts. ObservableCollection<T> notifies when the collection changes. It does not automatically mean the UI will react when a property on one existing item changes unless the item itself implements INotifyPropertyChanged.

csharp
1using System.ComponentModel;
2
3public class Person : INotifyPropertyChanged
4{
5    private string _name = "";
6
7    public string Name
8    {
9        get => _name;
10        set
11        {
12            if (_name == value) return;
13            _name = value;
14            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Name)));
15        }
16    }
17
18    public event PropertyChangedEventHandler? PropertyChanged;
19}

That is also relevant for BindingList<T>, but BindingList<T> has stronger built-in alignment with change-aware business objects and editing patterns in WinForms.

Sorting, Searching, and Advanced Binding

Out of the box, neither type is a magical full-featured data grid engine. However, BindingList<T> is closer to the component-model ecosystem where custom sorting, editing, and list metadata are common concerns. If you need advanced WinForms behavior, developers often extend BindingList<T> or use related types such as BindingSource.

ObservableCollection<T> is simpler. That simplicity is usually a benefit in XAML-style apps where the collection only needs to say "items were added or removed" and the framework handles the rest.

Example in WPF

csharp
1using System.Collections.ObjectModel;
2
3public class MainViewModel
4{
5    public ObservableCollection<Person> People { get; } =
6        new ObservableCollection<Person>
7        {
8            new Person { Name = "Alice" },
9            new Person { Name = "Bob" }
10        };
11}

Bound to a WPF ItemsControl, this is the idiomatic approach. The collection tells WPF when rows are added or removed, and each Person tells WPF when an individual property changes.

Example in WinForms

csharp
1using System.ComponentModel;
2
3public class Customer
4{
5    public string Name { get; set; } = "";
6}
7
8BindingList<Customer> customers = new BindingList<Customer>
9{
10    new Customer { Name = "Alice" },
11    new Customer { Name = "Bob" }
12};
13
14dataGridView1.DataSource = customers;

This style is common in WinForms because the binding infrastructure already understands BindingList<T> and ListChanged.

Which One Should You Choose

Choose based on the binding ecosystem, not on abstract preference:

  • use ObservableCollection<T> for WPF and similar XAML-based UIs
  • use BindingList<T> for WinForms-heavy data binding

If you are not doing UI binding at all, neither type may be necessary. A plain List<T> can be enough for non-observable in-memory data.

Common Pitfalls

  • Choosing ObservableCollection<T> in WinForms just because it sounds more modern. The framework may work better with BindingList<T>.
  • Assuming ObservableCollection<T> automatically reports property edits inside existing items. The items still need INotifyPropertyChanged when the UI must react to item changes.
  • Using BindingList<T> in WPF and then fighting the binding model instead of using the collection type the framework naturally expects.
  • Treating both classes as performance tools rather than notification tools. Their purpose is binding semantics, not faster collection operations.
  • Forgetting that a plain List<T> is often enough outside UI binding. Observable collections add complexity for a reason and should be used only when that reason exists.

Summary

  • 'ObservableCollection<T> is the usual choice for WPF-style collection binding.'
  • 'BindingList<T> is the usual choice for WinForms-style data binding.'
  • The main difference is the notification model: CollectionChanged versus ListChanged.
  • Item property updates still depend on the item type exposing its own change notifications when needed.
  • Pick the collection that matches the UI framework, not the one that merely looks more feature-rich.

Course illustration
Course illustration

All Rights Reserved.