dotnet/wpf · error · InvalidOperationException

SR.MoveInDeferSelectionActive

Error message

SR.MoveInDeferSelectionActive

What it means

SelectedItemCollection.MoveItem reorders an item in SelectedItems and is forbidden while _updatingSelectedItems is true. Moving items during the deferred selection commit would invalidate the SelectionChange state, so an InvalidOperationException is thrown (only when oldIndex != newIndex).

Solutions

  1. Call Move after the deferred selection scope has ended.
  2. Defer the Move with Dispatcher.BeginInvoke if it must react to a selection event.
  3. Don't reorder SelectedItems directly; operate on the underlying Items collection instead.
  4. Use UpdateSelectedItems only for Add/Remove of selections, not Move.

Example fix

// before
listBox.SelectedItems.Move(0, 2); // inside UpdateSelectedItems
// after
Dispatcher.BeginInvoke(new Action(() => listBox.SelectedItems.Move(0, 2)));
Defensive patterns

Strategy: validation

Validate before calling

if (oldIndex != newIndex && !isInsideUpdateSelectedItemsBlock) listBox.SelectedItems.Move(oldIndex, newIndex);

Try / catch

try { listBox.SelectedItems.Move(oldIndex, newIndex); }
catch (InvalidOperationException) { Dispatcher.BeginInvoke(new Action(() => listBox.SelectedItems.Move(oldIndex, newIndex))); }

Prevention

When it happens

Trigger: Calling SelectedItems.Move(oldIndex, newIndex) inside an UpdateSelectedItems block or from a callback invoked while selection change is active (SelectionChanged, OnSelectedCellsChanged, OnExecutedDelete).

Common situations: Reordering selected items from selection-change event handlers; drag-drop reordering implemented on SelectedItems during a bulk selection update.

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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/SelectedItemCollection.cs:127

                using (ChangeSelectedItems())
                {
                    base.SetItem(index, item);
                }
            }
        }

        /// <summary>
        /// Movea an item from one position to another
        /// </summary>
        /// <param name="oldIndex">index of the column which is being moved</param>
        /// <param name="newIndex">index of the column to be move to</param>
        protected override void MoveItem(int oldIndex, int newIndex)
        {
            if (oldIndex != newIndex)
            {
                if (_updatingSelectedItems)
                {
                    throw new InvalidOperationException(SR.MoveInDeferSelectionActive);
                }
                else
                {
                    using (ChangeSelectedItems())
                    {
                        base.MoveItem(oldIndex, newIndex);
                    }
                }
            }
        }

        #endregion

        #region Reentrant changes

        internal bool IsChanging { get { return (_changeCount > 0); } }

        private IDisposable ChangeSelectedItems()

View on GitHub (pinned to 81131a70a4)