dotnet/wpf · error · InvalidOperationException

SR.RoutedEventArgsMustHaveRoutedEvent

Error message

SR.RoutedEventArgsMustHaveRoutedEvent

What it means

RoutedEventArgs.RoutedEvent property setter throws this InvalidOperationException when the event args object has no associated RoutedEvent set. WPF routed event arguments must be tied to a RoutedEvent before properties like Source can be manipulated, because routing behavior depends on it. The library enforces this to keep the routed-event pipeline consistent.

Solutions

  1. Set the RoutedEvent property (or pass it to the constructor) before touching Source.
  2. Raise the event via UIElement.RaiseEvent so the framework initializes the args.
  3. If building custom args, use the constructor overload that accepts a RoutedEvent.

Example fix

// before
var args = new RoutedEventArgs();
element.RaiseEvent(args);
// after
var args = new RoutedEventArgs(MyControl.MyRoutedEvent);
element.RaiseEvent(args);
Defensive patterns

Strategy: validation

Validate before calling

if (args.RoutedEvent == null) throw new InvalidOperationException("Set RoutedEvent before using these args");

Try / catch

try { args.Source = target; } catch (InvalidOperationException ex) when (ex.Message.Contains("RoutedEvent")) { /* attach RoutedEvent and retry */ }

Prevention

When it happens

Trigger: Setting RoutedEventArgs.Source (or Handled/other guarded properties) on a RoutedEventArgs instance whose RoutedEvent field is still null — i.e. args constructed directly and never raised through RoutedEvent.RaiseEvent.

Common situations: Developers newing up RoutedEventArgs or a subclass and assigning Source manually before raising it; reusing event args outside a real RaiseEvent call; testing event args in isolation.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/c8594e5eed38e350. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/RoutedEventArgs.cs:130

        ///     Returns a boolean flag indicating if or not this
        ///     RoutedEvent has been handled this far in the route
        /// </summary>
        /// <remarks>
        ///     Initially starts with a false value before routing
        ///     has begun
        /// </remarks>
        public bool Handled
        {
            get
            {
                return _flags[ HandledIndex ] ;
            }

            set
            {
                if (_routedEvent == null)
                {
                    throw new InvalidOperationException(SR.RoutedEventArgsMustHaveRoutedEvent);
                }


                if( TraceRoutedEvent.IsEnabled )
                {
                    TraceRoutedEvent.TraceActivityItem(
                                            TraceRoutedEvent.HandleEvent,
                                            value,
                                            RoutedEvent.OwnerType.Name,
                                            RoutedEvent.Name,
                                            this );
                }


                // Note: We need to allow the caller to change the handled value
                // from true to false.
                //
                // We are concerned about scenarios where a child element

View on GitHub (pinned to 81131a70a4)