{"record":{"id":"0008cdd0736f17e1","repo":"dotnet/wpf","slug":"sr-setindeferselectionactive","errorCode":null,"errorMessage":"SR.SetInDeferSelectionActive","messagePattern":"SR\\.SetInDeferSelectionActive","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/SelectedItemCollection.cs","lineNumber":105,"sourceCode":"                }\n            }\n            else\n            {\n                using (ChangeSelectedItems())\n                {\n                    base.InsertItem(index, item);\n                }\n            }\n        }\n\n        /// <summary>\n        /// Sets an item on specified index\n        /// </summary>\n        protected override void SetItem(int index, object item)\n        {\n            if (_updatingSelectedItems)\n            {\n                throw new InvalidOperationException(SR.SetInDeferSelectionActive);\n            }\n            else\n            {\n                using (ChangeSelectedItems())\n                {\n                    base.SetItem(index, item);\n                }\n            }\n        }\n\n        /// <summary>\n        /// Movea an item from one position to another\n        /// </summary>\n        /// <param name=\"oldIndex\">index of the column which is being moved</param>\n        /// <param name=\"newIndex\">index of the column to be move to</param>\n        protected override void MoveItem(int oldIndex, int newIndex)\n        {\n            if (oldIndex != newIndex)","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/SelectedItemCollection.cs#L87-L123","documentation":"SelectedItemCollection.SetItem replaces an item at a given index and is disallowed while _updatingSelectedItems is true (i.e., between BeginUpdateSelectedItems and EndUpdateSelectedItems). Replacing items during a deferred selection commit would bypass the SelectionChange bookkeeping, so it throws InvalidOperationException.","triggerScenarios":"Calling SelectedItems[index] = newItem from inside an UpdateSelectedItems lambda/block, or via any code path that runs while the selection change is active (SelectionChanged handler, OnSelectedCellsChanged, MakeFullRowSelection).","commonSituations":"Custom DataGrid/ListBox selection code that tries to swap selected items inside selection-change callbacks; reentrancy from event handlers triggered during a bulk selection update.","solutions":["Perform the SetItem/assignment after EndUpdateSelectedItems completes.","Queue the change and apply it via Dispatcher once the deferred selection scope ends.","Avoid mutating SelectedItems inside SelectionChanged/cell-selection handlers; use UpdateSelectedItems instead.","Restructure logic to Add/Remove items rather than replace in place."],"exampleFix":"// before\nusing (deferredScope) { listBox.SelectedItems[0] = newItem; }\n// after\nusing (deferredScope) { /* deferred add/remove only */ }\nlistBox.SelectedItems[0] = newItem;","handlingStrategy":"validation","validationCode":"if (!isInsideUpdateSelectedItemsBlock) listBox.SelectedItems[index] = newItem;","typeGuard":null,"tryCatchPattern":"try { listBox.SelectedItems[index] = newItem; }\ncatch (InvalidOperationException) { Dispatcher.BeginInvoke(new Action(() => listBox.SelectedItems[index] = newItem)); }","preventionTips":["Apply SetItem outside deferred selection scopes.","Don't replace items from selection-change callbacks.","Restructure to Add/Remove instead of in-place replacement.","Keep a flag tracking whether code runs inside an update block."],"tags":["wpf","selector","selection","invalid-operation"],"backgroundTag":"invalid-state-transition","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-21T21:30:21.729Z"}