{"record":{"id":"016b1b42c20229d1","repo":"dotnet/wpf","slug":"sr-format-sr-mustbaseonstyleofabasetype-targettype-name","errorCode":null,"errorMessage":"SR.Format(SR.MustBaseOnStyleOfABaseType, _targetType.Name)","messagePattern":"SR\\.Format\\(SR\\.MustBaseOnStyleOfABaseType, _targetType\\.Name\\)","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Style.cs","lineNumber":501,"sourceCode":"            // 99% case - Style is already sealed.\n            if (_sealed)\n            {\n                return;\n            }\n\n            // Most parameter checking is done as \"upstream\" as possible, but some\n            //  can't be checked until Style is sealed.\n            if (_targetType == null)\n            {\n                throw new InvalidOperationException(SR.Format(SR.NullPropertyIllegal, \"TargetType\"));\n            }\n\n            if (_basedOn != null)\n            {\n                if(DefaultTargetType != _basedOn.TargetType &&\n                    !_basedOn.TargetType.IsAssignableFrom(_targetType))\n                {\n                    throw new InvalidOperationException(SR.Format(SR.MustBaseOnStyleOfABaseType, _targetType.Name));\n                }\n            }\n\n            // Seal setters\n            _setters?.Seal();\n\n            // Seal triggers\n            _visualTriggers?.Seal();\n\n            // Will throw InvalidOperationException if we find a loop of\n            //  BasedOn references.  (A.BasedOn = B, B.BasedOn = C, C.BasedOn = A)\n            CheckForCircularBasedOnReferences();\n\n            // Seal BasedOn Style chain\n            _basedOn?.Seal();\n\n            // Seal the ResourceDictionary\n            _resources?.IsReadOnly = true;","sourceCodeStart":483,"sourceCodeEnd":519,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Style.cs#L483-L519","documentation":"During Seal(), if a Style declares BasedOn, the base style's TargetType must equal this style's DefaultTargetType or be an assignable-from (base of) this style's TargetType. A BasedOn style targeting an unrelated or derived-incompatible type violates the inheritance contract and throws InvalidOperationException.","triggerScenarios":"style.BasedOn = otherStyle where otherStyle.TargetType is neither the same type nor a base type of this style's TargetType (e.g. a CheckBox style based on a Button style).","commonSituations":"Refactoring control types without updating BasedOn chains; merging resource dictionaries where a style key now points to a style with a different TargetType; typos in {StaticResource} keys resolving to a similarly-named style of another type.","solutions":["Make the derived style's TargetType match the base style's TargetType (or a subtype of it).","Choose a different base style whose TargetType is a base class of the current style's TargetType.","Remove BasedOn and re-declare the needed setters if no type-compatible base exists."],"exampleFix":"// before\nvar baseStyle = new Style(typeof(Button));\nvar derived = new Style(typeof(CheckBox)) { BasedOn = baseStyle }; // throws on Seal\n// after\nvar baseStyle = new Style(typeof(ToggleButton));\nvar derived = new Style(typeof(CheckBox)) { BasedOn = baseStyle };","handlingStrategy":"validation","validationCode":"if (baseStyle != null && derived.TargetType != null &&\n    baseStyle.TargetType != derived.TargetType &&\n    !baseStyle.TargetType.IsAssignableFrom(derived.TargetType))\n    throw new InvalidOperationException(\"BasedOn style targets an incompatible type.\");","typeGuard":"static bool BasedOnCompatible(Style derived, Style baseStyle) =>\n  baseStyle == null || baseStyle.TargetType == derived.TargetType || baseStyle.TargetType.IsAssignableFrom(derived.TargetType);","tryCatchPattern":"try { derived.Seal(); }\ncatch (InvalidOperationException ex) { log.Error(\"BasedOn TargetType incompatible\", ex); }","preventionTips":["Derive styles only from styles whose TargetType is the same or a base type.","Use a common base-type style (e.g. typeof(Control)) for shared BasedOn chains.","Verify StaticResource keys in BasedOn resolve to the intended type."],"tags":["wpf","style","basedon","type-hierarchy"],"backgroundTag":"type-mismatch","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"}