All Resources
Code Snippet.NET2026-03-05

WPF Data Binding with ObservableCollection

Bind a dynamic list of items to a WPF ListView or DataGrid using ObservableCollection and INotifyPropertyChanged. The core MVVM data binding pattern for .NET desktop apps.

csharp
public class PartViewModel : ObservableObject
{
    public ObservableCollection<Part> Parts { get; } = new();

    private Part? _selectedPart;
    public Part? SelectedPart
    {
        get => _selectedPart;
        set => SetProperty(ref _selectedPart, value);
    }

    public ICommand AddPartCommand => new RelayCommand(_ =>
    {
        Parts.Add(new Part { Name = "New Part", Quantity = 1 });
    });

    public ICommand RemovePartCommand => new RelayCommand(
        _ => Parts.Remove(SelectedPart!),
        _ => SelectedPart != null);
}

public class Part : ObservableObject
{
    private string _name = "";
    public string Name
    {
        get => _name;
        set => SetProperty(ref _name, value);
    }

    private int _quantity;
    public int Quantity
    {
        get => _quantity;
        set => SetProperty(ref _quantity, value);
    }
}

How It Works

ObservableCollection is the key to dynamic list binding in WPF. Unlike a regular List, it fires CollectionChanged events when items are added or removed, causing the UI to update automatically:

  1. ObservableCollection<Part> notifies the UI when items are added/removed
  2. INotifyPropertyChanged (via ObservableObject) notifies when individual properties change
  3. Commands (RelayCommand) let buttons add/remove items through the ViewModel

XAML Binding

In your View:

<ListView ItemsSource="{Binding Parts}"
          SelectedItem="{Binding SelectedPart}">
    <ListView.View>
        <GridView>
            <GridViewColumn Header="Name"
                DisplayMemberBinding="{Binding Name}" />
            <GridViewColumn Header="Qty"
                DisplayMemberBinding="{Binding Quantity}" />
        </GridView>
    </ListView.View>
</ListView>
<Button Content="Add" Command="{Binding AddPartCommand}" />
<Button Content="Remove" Command="{Binding RemovePartCommand}" />

Why Not Just Use List?

  • List<T>: No change notifications. If you add an item, the UI has no idea. You'd have to manually refresh the binding.
  • ObservableCollection<T>: Fires CollectionChanged on Add/Remove/Clear. The UI stays in sync automatically.
  • Important: ObservableCollection only notifies about collection changes (add/remove). For property changes on individual items, each item must implement INotifyPropertyChanged.

Tips

  • Use CommunityToolkit.Mvvm's ObservableObject base class for clean INotifyPropertyChanged implementation
  • For filtering/sorting, wrap in a CollectionViewSource rather than modifying the original collection
  • Avoid replacing the entire ObservableCollection — instead, Clear() and re-Add items to preserve bindings
WPFC#Data BindingMVVMObservableCollection