dotnet/wpf · error · InvalidOperationException
SR.CancelEditNotSupported
Error message
SR.CancelEditNotSupported
What it means
CancelEdit() supports true cancellation only when the edited item implements IEditableObject, in which case IEditableObject.CancelEdit() is invoked. If the item does not implement IEditableObject (and IEditableCollectionView mode is not 'simple'), the view throws InvalidOperationException because it cannot restore the item's prior state.
Solutions
- Implement IEditableObject on the item class (BeginEdit/CancelEdit/EndEdit) so the view can roll back changes.
- Wrap items in an editable view-model that snapshots state in BeginEdit and restores it in CancelEdit.
- Avoid CancelEdit for such items: snapshot values yourself before EditItem and restore manually.
- Check (view as IEditableCollectionView).CanCancelEdit before calling CancelEdit and handle the false case.
Example fix
// before
public class Customer {
public string Name { get; set; }
}
// after
public class Customer : IEditableObject {
public string Name { get; set; }
private string _backup;
public void BeginEdit() => _backup = Name;
public void CancelEdit() => Name = _backup;
public void EndEdit() => _backup = null;
} Defensive patterns
Strategy: validation
Validate before calling
// C#
var iecv = view as IEditableCollectionView;
if (iecv != null && !iecv.CanCancelEdit) { /* snapshot & restore manually instead */ } Type guard
bool SupportsCancelEdit(IEditableCollectionView v) => v.CanCancelEdit;
Try / catch
try { view.CancelEdit(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("CancelEdit")) { /* implement IEditableObject or restore manually */ } Prevention
- Implement IEditableObject on all editable item types.
- Check IEditableCollectionView.CanCancelEdit before CancelEdit.
- Keep a manual snapshot in your view-model for items that can't implement IEditableObject.
When it happens
Trigger: Calling CancelEdit() (or triggering it via DataGrid escape/UI) while the current edit item is a plain POCO that does not implement IEditableObject.
Common situations: Binding to a list of simple model classes without IEditableObject and pressing Escape in a DataGrid edit; expecting automatic rollback of property changes on objects that only implement INotifyPropertyChanged.
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
- ArgumentNullException(nameof(value))
- (no message) NotSupportedException
- NotImplementedException (ConvertBack not supported)
- NotImplementedException (ConvertBack not supported)
- NotSupportedException (ConvertBack not supported)
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/11c1b3a5f3474961.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Data/BindingListCollectionView.cs:1033
/// </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)