dotnet/wpf · error · ArgumentException
SR.HandlerTypeIllegal
Error message
SR.HandlerTypeIllegal
What it means
EventSetter.Seal checks that the Handler delegate's type matches the EventHandlerType of the routed Event. A mismatch throws ArgumentException with HandlerTypeIllegal, preventing a wrongly-typed delegate from being attached to the event.
Solutions
- Match the handler signature to the event: use MouseButtonEventHandler for MouseLeftButtonDown, etc.
- Change the Event to one that accepts the handler type you already have
- Wrap the existing method: Handler = new MouseButtonEventHandler((s,e) => OnClick(s, (RoutedEventArgs)e))
Example fix
// before
var es = new EventSetter {
Event = Mouse.MouseDownEvent, // needs MouseButtonEventHandler
Handler = new RoutedEventHandler(OnClick) };
// after
var es = new EventSetter {
Event = Mouse.MouseDownEvent,
Handler = new MouseButtonEventHandler(OnClick) }; Defensive patterns
Strategy: validation
Validate before calling
if (eventSetter.Handler != null && eventSetter.Event != null &&
eventSetter.Handler.GetType() != eventSetter.Event.HandlerType)
throw new InvalidOperationException($"Handler must be {eventSetter.Event.HandlerType.Name}"); Type guard
bool HandlerMatches(EventSetter s) => s.Handler.GetType() == s.Event.HandlerType;
Try / catch
try { style.Seal(); }
catch (ArgumentException ex) when (ex.Message.Contains("handler")) { recreateSetterWithCorrectDelegate(); } Prevention
- Match delegate types to each event's HandlerType
- Avoid copy-pasting EventSetter definitions between differently-typed events
When it happens
Trigger: Setting Event to a routed event whose handler type is, say, MouseButtonEventHandler, but supplying a RoutedEventHandler (or vice versa), then sealing the style.
Common situations: Copy-pasting EventSetter definitions between events with different signatures; changing the Event attribute in XAML without updating the Handler method signature.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- SR.Format(SR.InvalidSetterValue, value, dp.OwnerType…
- SR.Format(SR.MustBeFrameworkDerived, value.Name)
- SR.Format(SR.NullPropertyIllegal, "EventSetter.Event")
- SR.Format(SR.NullPropertyIllegal, "EventSetter.Handler")
- SR.Format(SR.StyleTargetTypeMismatchWithElement…
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/0229ba304639e0c0.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/EventSetter.cs:103
//
// Do the error checking that we can only do once all of the properties have been
// set, then call up to base.
//
internal override void Seal()
{
if (_event == null)
{
throw new ArgumentException(SR.Format(SR.NullPropertyIllegal, "EventSetter.Event"));
}
if (_handler == null)
{
throw new ArgumentException(SR.Format(SR.NullPropertyIllegal, "EventSetter.Handler"));
}
if (_handler.GetType() != _event.HandlerType)
{
throw new ArgumentException(SR.HandlerTypeIllegal);
}
base.Seal();
}
private RoutedEvent _event;
private Delegate _handler;
private bool _handledEventsToo;
}
}
View on GitHub (pinned to 81131a70a4)