{"record":{"id":"1b4650f2de1be4f4","repo":"dotnet/wpf","slug":"sr-styletriggerscannottargetthetemplate","errorCode":null,"errorMessage":"SR.StyleTriggersCannotTargetTheTemplate","messagePattern":"SR\\.StyleTriggersCannotTargetTheTemplate","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Style.cs","lineNumber":734,"sourceCode":"            if (style._visualTriggers != null)\n            {\n                // Merge in \"self\" and child TriggerBase PropertyValues while walking\n                // back up the tree. \"Based-on\" style rules are always added first\n                // (lower priority)\n                int triggerCount = style._visualTriggers.Count;\n                for (int i = 0; i < triggerCount; i++)\n                {\n                    TriggerBase trigger = style._visualTriggers[i];\n\n                    // Set things up to handle Setter values\n                    for (int j = 0; j < trigger.PropertyValues.Count; j++)\n                    {\n                        PropertyValue propertyValue = trigger.PropertyValues[j];\n\n                        // Check for trigger rules that act on container\n                        if (propertyValue.ChildName != StyleHelper.SelfName)\n                        {\n                            throw new InvalidOperationException(SR.StyleTriggersCannotTargetTheTemplate);\n                        }\n\n                        TriggerCondition[] conditions = propertyValue.Conditions;\n                        for (int k=0; k<conditions.Length; k++)\n                        {\n                            if( conditions[k].SourceName != StyleHelper.SelfName )\n                            {\n                                throw new InvalidOperationException(SR.Format(SR.TriggerOnStyleNotAllowedToHaveSource, conditions[k].SourceName));\n                            }\n                        }\n\n                        // Track properties on the container that are being driven by\n                        // the Style so that they can be invalidated during style changes\n                        StyleHelper.AddContainerDependent(propertyValue.Property, true /*fromVisualTrigger*/, ref this.ContainerDependents);\n\n                        StyleHelper.UpdateTables(ref propertyValue, ref ChildRecordFromChildIndex,\n                            ref TriggerSourceRecordFromChildIndex, ref ResourceDependents, ref _dataTriggerRecordFromBinding,\n                            null /*_childIndexFromChildID*/, ref _hasInstanceValues);","sourceCodeStart":716,"sourceCodeEnd":752,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Style.cs#L716-L752","documentation":"Style-level triggers (PropertyTrigger/VisualTrigger in Style.Triggers) may only act on the container element itself; a trigger's PropertyValues may not target a named child (ChildName != SelfName). Template targeting is reserved for triggers inside a ControlTemplate, so ProcessVisualTriggers throws InvalidOperationException (SR.StyleTriggersCannotTargetTheTemplate).","triggerScenarios":"A style MultiTrigger/Trigger whose Setter or condition is associated with a ChildName (from a template-derived or hand-built trigger) added to Style.Triggers, then sealed via Seal().","commonSituations":"Programmatically constructing Trigger objects reused between templates and styles; XAML tooling or code-gen emitting template-style triggers into Style.Triggers; deserialized triggers retaining ChildName data.","solutions":["Ensure every property value in the trigger has ChildName = StyleHelper.SelfName (no child targeting).","Move child-targeting triggers into the ControlTemplate where the named child exists.","Rebuild triggers for style use with plain property conditions only."],"exampleFix":"// before\nvar trigger = new Trigger { Property = UIElement.IsMouseOverProperty, Value = true };\ntrigger.Setters.Add(new Setter(TextBlock.ForegroundProperty, Brushes.Red) /* child-targeted pv */);\nstyle.Triggers.Add(trigger); // throws if propertyValue.ChildName != SelfName\n// after\nvar trigger = new Trigger { Property = UIElement.IsMouseOverProperty, Value = true };\ntrigger.Setters.Add(new Setter(Control.ForegroundProperty, Brushes.Red)); // container-only\nstyle.Triggers.Add(trigger);","handlingStrategy":"validation","validationCode":"foreach (var t in style.Triggers.OfType<TriggerBase>())\n    foreach (PropertyValue pv in /* trigger property values */ Enumerable.Empty<PropertyValue>())\n        if (pv.ChildName != StyleHelper.SelfName)\n            throw new InvalidOperationException(\"Style trigger targets a template child.\");","typeGuard":"static bool StyleTriggerIsContainerOnly(Trigger t) => t.Setters.OfType<Setter>().All(s => s.TargetName == null);","tryCatchPattern":"try { style.Seal(); }\ncatch (InvalidOperationException ex) { log.Error(\"Style trigger targets template\", ex); }","preventionTips":["Keep template-targeting triggers inside the ControlTemplate where the named child exists.","Never share Trigger instances between templates and styles.","Use container-scoped properties (self) for style trigger conditions and setters."],"tags":["wpf","style","triggers","template"],"backgroundTag":"invalid-argument-value","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-22T01:17:13.364Z"}