{"record":{"id":"22e0107eb0a88289","repo":"dotnet/wpf","slug":"sr-format-sr-cannotchangeaftersealed-setterbasecollection","errorCode":null,"errorMessage":"SR.Format(SR.CannotChangeAfterSealed, \"SetterBaseCollection\")","messagePattern":"SR\\.Format\\(SR\\.CannotChangeAfterSealed, \"SetterBaseCollection\"\\)","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/SetterBaseCollection.cs","lineNumber":101,"sourceCode":"        {\n            _sealed = true;\n\n            // Seal all the setters\n            for (int i=0; i<Count; i++)\n            {\n                this[i].Seal();\n            }\n        }\n\n        #endregion InternalMethods\n\n        #region PrivateMethods\n\n        private void CheckSealed()\n        {\n            if (_sealed)\n            {\n                throw new InvalidOperationException(SR.Format(SR.CannotChangeAfterSealed, \"SetterBaseCollection\"));\n            }\n        }\n\n        private void SetterBaseValidation(SetterBase setterBase)\n        {\n            ArgumentNullException.ThrowIfNull(setterBase);\n        }\n\n        #endregion PrivateMethods\n\n        #region Data\n\n        private bool _sealed;\n\n        #endregion Data\n    }\n}\n","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/SetterBaseCollection.cs#L83-L119","documentation":"SetterBaseCollection.CheckSealed throws InvalidOperationException when the collection is sealed (its owning style/template is in use). ClearItems, InsertItem, RemoveItem and SetItem all call it, so any add/remove/replace/clear on a sealed setter collection throws 'CannotChangeAfterSealed: SetterBaseCollection'.","triggerScenarios":"Calling style.Setters.Add/Remove/Clear on a style after it was applied to an element or explicitly sealed; shared resource-dictionary styles mutated at runtime.","commonSituations":"Hot-swapping setters in an in-use style; plugin code editing application-wide theme styles; tests reusing a cached Style object across assertions.","solutions":["Build a new Style (with BasedOn) with the desired setters and assign it to the element.","Perform all collection edits before the style is first applied/sealed.","If the style came from a resource dictionary, replace the dictionary entry with a new Style instance."],"exampleFix":"// before\nstyle.Setters.Clear(); // style already in use\n// after\nvar newStyle = new Style(style.TargetType, style);\nnewStyle.Setters.Add(new Setter(Control.BackgroundProperty, Brushes.Yellow));\nbutton.Style = newStyle;","handlingStrategy":"try-catch","validationCode":"if (style.IsSealed) { /* clone: new Style(style.TargetType, style) before edits */ }","typeGuard":null,"tryCatchPattern":"try { style.Setters.Add(newSetter); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"SetterBaseCollection\")) { /* build and assign a new Style */ }","preventionTips":["Never mutate Setters collections of styles in use; clone via BasedOn","Complete all collection edits before first application of the style"],"tags":["wpf","style","sealed","collection"],"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"}