{"record":{"id":"499c7edb79a7ba3a","repo":"dotnet/wpf","slug":"sr-triggerssupportseventtriggersonly","errorCode":null,"errorMessage":"SR.TriggersSupportsEventTriggersOnly","messagePattern":"SR\\.TriggersSupportsEventTriggersOnly","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/EventTrigger.cs","lineNumber":321,"sourceCode":"            if( eventTrigger != null )\n            {\n                Debug.Assert( eventTrigger._routedEventHandler == null && eventTrigger._source == null);\n                \n                // PERF: Cache this result if it turns out we're doing a lot of lookups on the same name.\n                eventTrigger._source = FrameworkElement.FindNamedFrameworkElement( triggersHost, eventTrigger.SourceName );\n\n                // Create a statefull event delegate (which keeps a ref to the FE).\n                EventTriggerSourceListener listener = new EventTriggerSourceListener( eventTrigger, triggersHost );\n\n\n                // Store the RoutedEventHandler & target for use in DisconnectOneTrigger\n                eventTrigger._routedEventHandler = new RoutedEventHandler(listener.Handler);\n                eventTrigger._source.AddHandler( eventTrigger.RoutedEvent, eventTrigger._routedEventHandler,\n                                                 false /* HandledEventsToo */ );\n            }\n            else\n            {\n                throw new InvalidOperationException(SR.TriggersSupportsEventTriggersOnly);\n            }\n        }\n\n        ////////////////////////////////////////////////////////////////////////\n        //\n        // DisconnectAllTriggers\n        //\n        // Call DisconnectOneTrigger for each trigger in the Triggers collection.\n\n        internal static void DisconnectAllTriggers( FrameworkElement triggersHost )\n        {\n            TriggerCollection triggerCollection = TriggerCollectionField.GetValue(triggersHost);\n\n            if( triggerCollection != null )\n            {\n                for( int i = 0; i < triggerCollection.Count; i++ )\n                {\n                    DisconnectOneTrigger( triggersHost, triggerCollection[i] );","sourceCodeStart":303,"sourceCodeEnd":339,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/EventTrigger.cs#L303-L339","documentation":"During trigger processing (StyleHelper.ProcessTriggerCollection), a trigger in a FrameworkTemplate's trigger collection is not an EventTrigger, so ProcessOneTrigger cannot attach its event handler and throws. Template triggers support only EventTrigger; property triggers belong in Style.Triggers.","triggerScenarios":"Placing a Trigger, MultiTrigger, or DataTrigger inside a ControlTemplate/FrameworkTemplate's Triggers collection, which is then processed when the template is instantiated.","commonSituations":"Copying trigger XAML from a Style into a ControlTemplate; believing ControlTemplate.Triggers accepts DataTrigger; tooling that emits generic trigger elements inside templates.","solutions":["Convert the trigger to an EventTrigger (only type allowed in ControlTemplate.Triggers).","Move property/data triggers from the template into the Style's Triggers collection (Style.Triggers).","Use VisualStateManager states inside the template instead of property triggers."],"exampleFix":"<!-- before -->\n<ControlTemplate>\n  <ControlTemplate.Triggers>\n    <Trigger Property=\"IsMouseOver\" Value=\"True\">...</Trigger>\n  </ControlTemplate.Triggers>\n</ControlTemplate>\n\n<!-- after -->\n<Style>\n  <Style.Triggers>\n    <Trigger Property=\"IsMouseOver\" Value=\"True\">...</Trigger>\n  </Style.Triggers>\n</Style>","handlingStrategy":"validation","validationCode":"foreach (var t in template.Triggers)\n    if (t is not EventTrigger)\n        throw new InvalidOperationException(\"ControlTemplate.Triggers supports only EventTrigger.\");","typeGuard":"bool IsTemplateTrigger(TriggerBase t) => t is EventTrigger;","tryCatchPattern":"try { ApplyTemplate(el); }\ncatch (InvalidOperationException) { /* move non-event triggers into Style.Triggers */ }","preventionTips":["Only declare EventTrigger in ControlTemplate.Triggers.","Place Trigger/DataTrigger/MultiTrigger in Style.Triggers instead.","Prefer VisualStateManager inside templates for state-based visuals."],"tags":["wpf","xaml","type-mismatch","controltemplate"],"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"}