dotnet/wpf · error · InvalidOperationException

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

Error message

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

What it means

SortDescriptionsChanged throws InvalidOperationException (SR.MemberNotAllowedDuringAddOrEdit, "Sorting") when the SortDescriptions collection changes while the view is in the middle of an AddNew or EditItem transaction. WPF forbids changing sorting during an pending add/edit because it would invalidate the transaction.

Solutions

  1. Call CommitNew() and CommitEdit() before changing SortDescriptions.
  2. Guard sorting changes: if (view.IsAddingNew) view.CommitNew(); if (view.IsEditingItem) view.CommitEdit(); then apply sorts.
  3. Use CancelNew()/CancelEditItem appropriately to abort the transaction before sorting.
  4. Defer the sort-description change until the transaction completes (e.g. queue it for after CommitEdit).

Example fix

// before
view.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending)); // may throw mid-transaction

// after
if (view.IsAddingNew) view.CommitNew();
if (view.IsEditingItem) view.CommitEdit();
view.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending));
Defensive patterns

Strategy: validation

Validate before calling

if (view.IsAddingNew) view.CommitNew();
if (view.IsEditingItem) view.CommitEdit();
view.SortDescriptions.Add(sortDescription);

Type guard

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

Try / catch

try { view.SortDescriptions.Clear(); }
catch (InvalidOperationException) { view.CommitEdit(); view.SortDescriptions.Clear(); }

Prevention

When it happens

Trigger: Calling view.SortDescriptions.Add/Remove/Clear (or changing grouping) while IsAddingNew or IsEditingItem is true — i.e. between AddNew()/CommitNew or EditItem()/CommitEdit calls.

Common situations: UI code that re-sorts or re-applies sort descriptions (e.g. on a column-header click) while an edit or add-new is still pending because a previous CommitNew/CommitEdit was never invoked; event handlers updating sorting during data entry.

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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Data/BindingListCollectionView.cs:2169

            get { return ((_blv != null) && !String.IsNullOrEmpty(_customFilter)); }
        }

        // can the group name(s) for an item change after we've grouped the item?
        private bool CanGroupNamesChange
        {
            // There's no way we can deduce this - the app has to tell us.
            // If this is true, removing a grouped item is quite difficult.
            // We cannot rely on its group names to tell us which group we inserted
            // it into (they may have been different at insertion time), so we
            // have to do a linear search.
            get { return true; }
        }

        // SortDescription was added/removed, refresh CollView
        private void SortDescriptionsChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            if (IsAddingNew || IsEditingItem)
                throw new InvalidOperationException(SR.Format(SR.MemberNotAllowedDuringAddOrEdit, "Sorting"));

            RefreshOrDefer();
        }

        // convert from Avalon SortDescriptions to the corresponding .NET collection
        private ListSortDescriptionCollection ConvertSortDescriptionCollection(SortDescriptionCollection sorts)
        {
            PropertyDescriptorCollection pdc;
            ITypedList itl;
            Type itemType;

            if ((itl = InternalList as ITypedList) != null)
            {
                pdc = itl.GetItemProperties(null);
            }
            else if ((itemType = GetItemType(true)) != null)
            {
                pdc = TypeDescriptor.GetProperties(itemType);

View on GitHub (pinned to 81131a70a4)