{"record":{"id":"86d6d25fdd98861d","repo":"dotnet/wpf","slug":"sr-deferselectionnotactive","errorCode":null,"errorMessage":"SR.DeferSelectionNotActive","messagePattern":"SR\\.DeferSelectionNotActive","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/SelectedItemCollection.cs","lineNumber":201,"sourceCode":"        /// </summary>\n        internal void BeginUpdateSelectedItems()\n        {\n            if (_selector.SelectionChange.IsActive || _updatingSelectedItems)\n            {\n                throw new InvalidOperationException(SR.DeferSelectionActive);\n            }\n            _updatingSelectedItems = true;\n            _selector.SelectionChange.Begin();\n        }\n\n        /// <summary>\n        /// Commit selection changes.\n        /// </summary>\n        internal void EndUpdateSelectedItems()\n        {\n            if (!_selector.SelectionChange.IsActive || !_updatingSelectedItems)\n            {\n                throw new InvalidOperationException(SR.DeferSelectionNotActive);\n            }\n            _updatingSelectedItems = false;\n            _selector.SelectionChange.End();\n        }\n\n        /// <summary>\n        /// Returns true after BeginUpdateSelectedItems is called\n        /// </summary>\n        internal bool IsUpdatingSelectedItems\n        {\n            get\n            {\n                return _selector.SelectionChange.IsActive || _updatingSelectedItems;\n            }\n        }\n\n        /// <summary>\n        /// Add an ItemInfo to the deferred selection","sourceCodeStart":183,"sourceCodeEnd":219,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/SelectedItemCollection.cs#L183-L219","documentation":"EndUpdateSelectedItems commits the queued selection changes and must only be called while a deferred selection is actually active (SelectionChange.IsActive AND _updatingSelectedItems). Calling it without a matching BeginUpdateSelectedItems — or after the selection change already ended — throws InvalidOperationException (DeferSelectionNotActive).","triggerScenarios":"Calling EndUpdateSelectedItems without a prior successful BeginUpdateSelectedItems; calling it twice; calling it from code paths (OnExecutedDelete, OnSelectedCellsChanged, MakeFullRowSelection, UpdateSelectedItems) when the underlying SelectionChange was terminated early (e.g. by an exception between Begin and End).","commonSituations":"Unbalanced try/finally around Begin/End; an exception inside the update block leaves state inconsistent; custom code mimicking DataGrid internals calls End without Begin.","solutions":["Always pair Begin/End in a try/finally so End runs only after a successful Begin.","Ensure End is called exactly once per Begin.","Catch exceptions inside the update block so the scope is properly committed or rolled back.","Avoid hand-rolling Begin/End; use Selector.UpdateSelectedItems which manages the scope."],"exampleFix":"// before\nlistBox.BeginUpdateSelectedItems(); DoWork(); listBox.EndUpdateSelectedItems();\n// after\nlistBox.BeginUpdateSelectedItems();\ntry { DoWork(); }\nfinally { listBox.EndUpdateSelectedItems(); }","handlingStrategy":"validation","validationCode":"if (beganUpdate && !endedUpdate) EndUpdateSelectedItems();","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pair Begin/End in try/finally.","Call End exactly once per Begin.","Catch exceptions inside the update block to keep the scope consistent.","Prefer Selector.UpdateSelectedItems over manual Begin/End."],"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"}