dotnet/wpf · error · InvalidOperationException

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

Error message

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

What it means

ListCollectionView.CustomSort cannot be assigned while an AddNew or EditItem transaction is open. Setting CustomSort triggers a sort/refresh, which the view forbids mid-transaction, so it throws InvalidOperationException.

Solutions

  1. Commit or cancel the pending transaction (CommitNew/CommitEdit/CancelNew/CancelEdit) before setting CustomSort
  2. Guard the assignment with IsAddingNew/IsEditingItem checks
  3. Reapply the CustomSort after the transaction ends, e.g. on CollectionView transaction-completion events

Example fix

// before
view.CustomSort = comparer; // throws during AddNew
// after
if (view.IsAddingNew) view.CommitNew();
if (view is IEditableCollectionView ecv && ecv.IsEditingItem) ecv.CommitEdit();
view.CustomSort = comparer;
Defensive patterns

Strategy: validation

Validate before calling

var ecv = collectionView as IEditableCollectionView;
if (!(collectionView.IsAddingNew || (ecv != null && ecv.IsEditingItem)))
    collectionView.CustomSort = comparer;

Try / catch

try { view.CustomSort = comparer; }
catch (InvalidOperationException)
{
    // postpone sort until the current transaction completes
}

Prevention

When it happens

Trigger: Setting the CustomSort property (IComparer) after AddNew() or EditItem() started a transaction that was not committed or cancelled.

Common situations: Applying custom sorting from UI events (column header clicks, combo selection) while a DataGrid is adding or editing a row; code that reassigns the comparer after data edits without closing the transaction.

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

Appendix: source

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

        #endregion ICollectionView

        /// <summary>
        /// Set a custom comparer to sort items using an object that implements IComparer.
        /// </summary>
        /// <remarks>
        /// Setting the Sort criteria has no immediate effect,
        /// an explicit <seealso cref="CollectionView.Refresh"/> call by the app is required.
        /// Note: Setting the custom comparer object will clear previously set <seealso cref="CollectionView.SortDescriptions"/>.
        /// </remarks>
        public IComparer CustomSort
        {
            get { return _customSort; }
            set
            {
                if (AllowsCrossThreadChanges)
                    VerifyAccess();
                if (IsAddingNew || IsEditingItem)
                    throw new InvalidOperationException(SR.Format(SR.MemberNotAllowedDuringAddOrEdit, "CustomSort"));
                _customSort = value;

                SetSortDescriptions(null);

                RefreshOrDefer();
            }
        }

        /// <summary>
        /// A delegate to select the group description as a function of the
        /// parent group and its level.
        /// </summary>
        [DefaultValue(null)]
        public virtual GroupDescriptionSelectorCallback GroupBySelector
        {
            get { return _group.GroupBySelector; }
            set
            {

View on GitHub (pinned to 81131a70a4)