dotnet/wpf · error · InvalidOperationException

SR.Format(SR.MemberNotAllowedDuringTransaction…

Error message

SR.Format(SR.MemberNotAllowedDuringTransaction, "CancelEdit", "AddNew")

What it means

CancelEdit throws InvalidOperationException when the view is in an AddNew transaction. CancelEdit only rolls back an EditItem transaction; with an add pending, CancelNew is the matching operation, so the view rejects CancelEdit to keep the transaction pair consistent.

Solutions

  1. Call CancelNew() when IsAddingNew instead of CancelEdit().
  2. Branch on transaction state before cancelling: IsAddingNew -> CancelNew, IsEditingItem -> CancelEdit.
  3. Fix code paths that open AddNew and later attempt edit-style cleanup.

Example fix

// before
collectionView.CancelEdit();

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

Strategy: validation

Validate before calling

if (view.IsAddingNew) view.CancelNew();
else if (view.IsEditingItem) view.CancelEdit();

Type guard

bool CanCancelEdit(ICollectionView v) => !v.IsAddingNew && v.IsEditingItem;

Try / catch

try { view.CancelEdit(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("CancelEdit"))
{ view.CancelNew(); /* matching operation for add transaction */ }

Prevention

When it happens

Trigger: Calling view.CancelEdit() while IsAddingNew is true (AddNew is open and CommitNew/CancelNew was never called).

Common situations: Generic 'cancel' buttons wired to CancelEdit that run while a new-item row is being added; error handlers that always cancel edits on failure without checking the transaction type.

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/d61c55ed3f4b5bb5. Report an issue: GitHub.

Appendix: source

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

                    toIndex = AdjustBefore(NotifyCollectionChangedAction.Add, editItem, SourceList.IndexOf(editItem));
                    ProcessCollectionChangedWithAdjustedIndex(
                                new NotifyCollectionChangedEventArgs(
                                            NotifyCollectionChangedAction.Add,
                                            editItem,
                                            toIndex+delta),
                                -1, toIndex+delta);
                }
            }
        }

        /// <summary>
        /// Complete the transaction started by <seealso cref="EditItem"/>.
        /// The pending changes (if any) to the item are discarded.
        /// </summary>
        public void CancelEdit()
        {
            if (IsAddingNew)
                throw new InvalidOperationException(SR.Format(SR.MemberNotAllowedDuringTransaction, "CancelEdit", "AddNew"));
            VerifyRefreshNotDeferred();

            if (_editItem == null)
                return;

            IEditableObject ieo = _editItem as IEditableObject;
            SetEditItem(null);

            if (ieo != null)
            {
                ieo.CancelEdit();
            }
            else
                throw new InvalidOperationException(SR.CancelEditNotSupported);
        }

        private void ImplicitlyCancelEdit()
        {

View on GitHub (pinned to 81131a70a4)