dotnet/wpf · error · InvalidOperationException

SR.Format(SR.MemberNotAllowedDuringAddOrEdit, "Remove")

Error message

SR.Format(SR.MemberNotAllowedDuringAddOrEdit, "Remove")

What it means

ListCollectionView.Remove(object) throws InvalidOperationException when the view has a pending AddNew or EditItem transaction. As with RemoveAt, removing an item is forbidden during an add/edit transaction to keep the pending item state consistent.

Solutions

  1. End the transaction first: CommitNew()/CancelNew() when IsAddingNew, CommitEdit()/CancelEdit() when IsEditingItem, then call Remove.
  2. Check view.IsAddingNew / view.IsEditingItem before removing and skip or queue the removal otherwise.
  3. Use ICollectionView.Refresh or rebind after ending the transaction if the view state seems stale.

Example fix

// before
collectionView.Remove(selectedItem);

// after
if (collectionView.IsAddingNew) collectionView.CancelNew();
if (collectionView.IsEditingItem) collectionView.CancelEdit();
collectionView.Remove(selectedItem);
Defensive patterns

Strategy: validation

Validate before calling

if (view.IsAddingNew) view.CommitNew();
if (view.IsEditingItem) view.CommitEdit();
// now safe:
view.Remove(item);

Type guard

bool CanRemove(ICollectionView v, object item) => !v.IsAddingNew && !v.IsEditingItem && !Equals(item, CollectionView.NewItemPlaceholder);

Try / catch

try { view.Remove(item); }
catch (InvalidOperationException ex) when (ex.Message.Contains("NotAllowedDuringAddOrEdit"))
{ /* commit/cancel then retry */ }

Prevention

When it happens

Trigger: Calling view.Remove(item) after AddNew() without CommitNew()/CancelNew(), or after EditItem(item) without CommitEdit()/CancelEdit().

Common situations: Programmatic deletes issued while a DataGrid row is in edit mode; a delete command bound to a button that remains enabled during add-new.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Data/ListCollectionView.cs:1062

        /// The index is interpreted with respect to the view (not with respect to
        /// the underlying collection).
        /// </summary>
        public void RemoveAt(int index)
        {
            if (IsEditingItem || IsAddingNew)
                throw new InvalidOperationException(SR.Format(SR.MemberNotAllowedDuringAddOrEdit, "RemoveAt"));
            VerifyRefreshNotDeferred();

            RemoveImpl(GetItemAt(index), index);
        }

        /// <summary>
        /// Remove the given item from the underlying collection.
        /// </summary>
        public void Remove(object item)
        {
            if (IsEditingItem || IsAddingNew)
                throw new InvalidOperationException(SR.Format(SR.MemberNotAllowedDuringAddOrEdit, "Remove"));
            VerifyRefreshNotDeferred();

            int index = InternalIndexOf(item);
            if (index >= 0)
            {
                RemoveImpl(item, index);
            }
        }

        private void RemoveImpl(object item, int index)
        {
            if (item == CollectionView.NewItemPlaceholder)
                throw new InvalidOperationException(SR.RemovingPlaceholder);

            BindingOperations.AccessCollection(SourceList,
                () =>
                {
                    ProcessPendingChanges();

View on GitHub (pinned to 81131a70a4)