{"record":{"id":"1e354c5a313f7a1e","repo":"dotnet/wpf","slug":"sr-handlertypeillegal-frameworkelementfactory","errorCode":null,"errorMessage":"SR.HandlerTypeIllegal","messagePattern":"SR\\.HandlerTypeIllegal","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/FrameworkElementFactory.cs","lineNumber":310,"sourceCode":"            AddHandler(routedEvent, handler, false);\n        }\n\n        /// <summary>\n        ///     Add an event handler for the given routed event. This action applies to the instances created by this factory\n        /// </summary>\n        public void AddHandler(RoutedEvent routedEvent, Delegate handler, bool handledEventsToo)\n        {\n            if (_sealed)\n            {\n                throw new InvalidOperationException(SR.Format(SR.CannotChangeAfterSealed, \"FrameworkElementFactory\"));\n            }\n\n            ArgumentNullException.ThrowIfNull(routedEvent);\n            ArgumentNullException.ThrowIfNull(handler);\n\n            if (handler.GetType() != routedEvent.HandlerType)\n            {\n                throw new ArgumentException(SR.HandlerTypeIllegal);\n            }\n\n            if (_eventHandlersStore == null)\n            {\n                _eventHandlersStore = new EventHandlersStore();\n            }\n\n            _eventHandlersStore.AddRoutedEventHandler(routedEvent, handler, handledEventsToo);\n\n            // Keep track of whether we're listening to the loaded or unloaded events;\n            // if so, we have to trigger a listener in the FE/FCE (as a performance\n            // optimization).\n\n            if (  (routedEvent == FrameworkElement.LoadedEvent)\n                ||(routedEvent == FrameworkElement.UnloadedEvent))\n            {\n                HasLoadedChangeHandler = true;\n            }","sourceCodeStart":292,"sourceCodeEnd":328,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/FrameworkElementFactory.cs#L292-L328","documentation":"AddHandler throws ArgumentException when the handler delegate's concrete type does not exactly match routedEvent.HandlerType. Unlike CLR events, routed events require the delegate type to match exactly (e.g. RoutedEventHandler for Click), not just be compatible via assignment. The check is strict equality of the handler's runtime type.","triggerScenarios":"Calling factory.AddHandler(routedEvent, handler) where handler.GetType() != routedEvent.HandlerType — e.g. passing a RoutedEventHandler to an event expecting a MouseButtonEventHandler, or a lambda cast to the wrong delegate type.","commonSituations":"Reusing one handler method for multiple events and wrapping it in the wrong delegate type; generic or custom delegate declarations that compile but don't match the routed event's HandlerType.","solutions":["Wrap the method in the exact delegate type: routedEvent.HandlerType, e.g. new RoutedEventHandler(OnClick) for Click.","Check routedEvent.HandlerType at runtime to see the required delegate type.","Declare handler variables with the specific delegate type instead of Delegate/Action."],"exampleFix":"// before\nDelegate h = new MouseButtonEventHandler(OnClick);\nfactory.AddHandler(ButtonBase.ClickEvent, h);\n// after\nRoutedEventHandler h = OnClick;\nfactory.AddHandler(ButtonBase.ClickEvent, h);","handlingStrategy":"type-guard","validationCode":"if (handler.GetType() != routedEvent.HandlerType)\n    throw new ArgumentException($\"Handler must be {routedEvent.HandlerType.Name}\");","typeGuard":"static bool IsMatchingHandler(RoutedEvent e, Delegate h) => h.GetType() == e.HandlerType;","tryCatchPattern":"try { factory.AddHandler(routedEvent, handler); }\ncatch (ArgumentException) { var typed = Delegate.CreateDelegate(routedEvent.HandlerType, handler.Target, handler.Method); factory.AddHandler(routedEvent, typed); }","preventionTips":["Declare handler variables with the exact routed-event delegate type.","Inspect routedEvent.HandlerType before wrapping a method.","Avoid Delegate/Action variables when calling AddHandler."],"tags":["wpf","routed-events","delegate"],"backgroundTag":"type-mismatch","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"}