dotnet/wpf · error · ArgumentException

SR.DuplicateEventName

Error message

SR.DuplicateEventName

What it means

EventManager.RegisterRoutedEvent enforces that a routed event name is unique per owner type. If GlobalEventManager.GetRoutedEventFromName(name, ownerType, false) already returns an event, it throws ArgumentException with SR.DuplicateEventName. Registering the same (name, ownerType) pair twice would otherwise create ambiguous event lookups.

Solutions

  1. Use RoutedEvent.Register only once, typically in a static readonly field
  2. Look up with EventManager.GetRoutedEvent(name, ownerType) and reuse if non-null before registering
  3. Ensure the type is not loaded/initialized twice in the app domain

Example fix

// before
public static readonly RoutedEvent MyEvent =
    EventManager.RegisterRoutedEvent("My", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(MyControl));
// duplicate second call with same name+ownerType throws
// after
public static readonly RoutedEvent MyEvent =
    EventManager.GetRoutedEvent("My", typeof(MyControl))
    ?? EventManager.RegisterRoutedEvent("My", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(MyControl));
Defensive patterns

Strategy: validation

Validate before calling

if (EventManager.GetRoutedEvent(name, ownerType) == null) { /* safe to register */ }

Try / catch

try { evt = EventManager.RegisterRoutedEvent(name, RoutingStrategy.Bubble, h, ownerType); } catch (ArgumentException) { evt = EventManager.GetRoutedEvent(name, ownerType); }

Prevention

When it happens

Trigger: Calling RegisterRoutedEvent with the same name and ownerType more than once — typically static registration code that runs twice (e.g. in both a static ctor and a module initializer), or registering in a base class and an identical name in the derived owner type reusing the same ownerType.

Common situations: Unit tests re-running static registration; assembly loaded twice in different contexts causing static initializers to double-register; copy-pasted registration code in two types with the same name/ownerType arguments.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/EventManager.cs:70

            Type handlerType,
            Type ownerType)
        {
            ArgumentNullException.ThrowIfNull(name);

            if (routingStrategy != RoutingStrategy.Tunnel && 
                routingStrategy != RoutingStrategy.Bubble &&
                routingStrategy != RoutingStrategy.Direct) 
            {
                throw new System.ComponentModel.InvalidEnumArgumentException("routingStrategy", (int)routingStrategy, typeof(RoutingStrategy));
            }

            ArgumentNullException.ThrowIfNull(handlerType);

            ArgumentNullException.ThrowIfNull(ownerType);

            if (GlobalEventManager.GetRoutedEventFromName(name, ownerType, false) != null)
            {
                throw new ArgumentException(SR.Format(SR.DuplicateEventName, name, ownerType)); 
            }

            return GlobalEventManager.RegisterRoutedEvent(name, routingStrategy, handlerType, ownerType);
        }

        /// <summary>
        ///     See overloaded method for details
        /// </summary>
        /// <remarks>
        ///     handledEventsToo defaults to false
        ///     See overloaded method for details
        /// </remarks>
        /// <param name="classType"/>
        /// <param name="routedEvent"/>
        /// <param name="handler"/>
        /// <ExternalAPI/>
        public static void RegisterClassHandler(
            Type classType,

View on GitHub (pinned to 81131a70a4)