dotnet/wpf · error · InvalidOperationException

SR.CancelEditNotSupported

Error message

SR.CancelEditNotSupported

What it means

CancelEdit throws InvalidOperationException when the item being edited does not implement IEditableObject. Without IEditableObject, the view has no way to roll back the item's changes, so an explicit CancelEdit is unsupported (pending changes cannot be discarded).

Solutions

  1. Make the edited item class implement IEditableObject (BeginEdit/EndEdit/CancelEdit) so changes can be rolled back.
  2. Commit the edit (CommitEdit) instead of cancelling, since cancellation is unsupported for non-IEditableObject items.
  3. Snapshot values manually before EditItem and restore them yourself instead of relying on CancelEdit.

Example fix

// before
class Customer : INotifyPropertyChanged { ... }
view.EditItem(customer);
view.CancelEdit(); // throws

// after
class Customer : INotifyPropertyChanged, IEditableObject
{
    public void BeginEdit() { _snapshot = CloneState(); }
    public void CancelEdit() { RestoreState(_snapshot); }
    public void EndEdit() { _snapshot = null; }
}
Defensive patterns

Strategy: validation

Validate before calling

if (view.IsEditingItem && !(view.CurrentEditItem is IEditableObject))
    view.CommitEdit(); // cannot CancelEdit non-IEditableObject item
else
    view.CancelEdit();

Type guard

bool SupportsCancelEdit(object editItem) => editItem is IEditableObject;

Try / catch

try { view.CancelEdit(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("CancelEdit"))
{ /* fall back: CommitEdit or manually restore values */ }

Prevention

When it happens

Trigger: Calling view.CancelEdit() (or ImplicitlyCancelEdit paths like Refresh) while _editItem is a plain object that does not implement System.ComponentModel.IEditableObject.

Common situations: Editing POCO/view-model classes that only implement INotifyPropertyChanged but not IEditableObject, then trying to cancel an edit; framework refresh during an open edit transaction on such an item.

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

Appendix: source

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

        /// </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()
        {
            IEditableObject ieo = _editItem as IEditableObject;
            SetEditItem(null);

            ieo?.CancelEdit();
        }

        /// <summary>
        /// Returns true if the view supports the notion of "pending changes" on the
        /// current edit item.  This may vary, depending on the view and the particular
        /// item.  For example, a view might return true if the current edit item
        /// implements <seealso cref="IEditableObject"/>, or if the view has special
        /// knowledge about the item that it can use to support rollback of pending
        /// changes.
        /// </summary>

View on GitHub (pinned to 81131a70a4)