dotnet/wpf · error

The ItemsSource for the DataGridCellsPresenter is read-only.

Error message

The ItemsSource for the DataGridCellsPresenter is read-only.

What it means

MultipleCopiesCollection is the read-only collection the DataGridCellsPresenter exposes as its ItemsSource, containing one copy of the row's cell item per column. IList.Add is deliberately non-functional and throws NotSupportedException (SR.DataGrid_ReadonlyCellsItemsSource) because the collection is generated and owned by the DataGrid from its columns; callers must never mutate it.

Solutions

  1. Do not modify the cells collection; add or remove DataGridColumns on the owning DataGrid.Columns — cells are regenerated from columns.
  2. Customize cell appearance via Column.CellTemplate/CellStyle or DataGrid events (AutoGeneratingColumn, LoadingRow) instead of injecting cells.
  3. Project to a new List via LINQ (ToList) when you need a modifiable copy.
  4. Catch NotSupportedException at the boundary if consuming third-party code, treating it as a signal the collection is DataGrid-managed.

Example fix

// before: ((IList)cellsPresenter.Items).Add(new DataGridCell()); // throws NotSupportedException // after: dataGrid.Columns.Add(new DataGridTextColumn { Header = "New", Binding = new Binding("Prop") });
Defensive patterns

Strategy: validation

Validate before calling

static bool CanAddItems(ItemsControl presenter) => !(presenter is DataGridCellsPresenter) && !((IList)presenter.Items).IsReadOnly;

Type guard

static bool IsMutableList(object list) => list is IList l && !l.IsReadOnly;

Try / catch

try { cells.Add(newCell); } catch (NotSupportedException ex) when (ex.Message.Contains("read-only")) { dataGrid.Columns.Add(new DataGridTextColumn { Header = "New" }); }

Prevention

When it happens

Trigger: Calling Add on DataGridCellsPresenter.Items or its ItemsSource, directly or through an IList reference (e.g. ((IList)presenter.Items).Add(obj)); also if ItemsControl machinery attempts to add into it.

Common situations: Trying to append an extra cell to a DataGrid row programmatically; automation/test code that manipulates cell collections; reusing code written against normal editable ItemsControl collections.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/413cf51ee640b81d. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/MultipleCopiesCollection.cs:230

        private void OnReplace(object oldItem, object newItem, int index)
        {
            OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, newItem, oldItem, index));
        }

        private void Reset()
        {
            RepeatCount = 0;
            OnCollectionReset();
        }

        #endregion

        #region IList Members

        public int Add(object value)
        {
            throw new NotSupportedException(SR.DataGrid_ReadonlyCellsItemsSource);
        }

        public void Clear()
        {
            throw new NotSupportedException(SR.DataGrid_ReadonlyCellsItemsSource);
        }

        public bool Contains(object value)
        {
            ArgumentNullException.ThrowIfNull(value);

            return _item == value;
        }

        public int IndexOf(object value)
        {
            ArgumentNullException.ThrowIfNull(value);

View on GitHub (pinned to 81131a70a4)