stride3d/stride · error · ArgumentException

The EventName property must be set on behavior

Error message

The EventName property must be set on behavior '{GetType().FullName}'.

What it means

OnEventBehavior.OnAttached throws ArgumentException when the EventName attached property was not set before the behavior attaches to its associated object. The behavior needs an event name to resolve and subscribe to. The message includes the behavior's concrete type to help locate the misconfigured XAML.

Solutions

  1. Set EventName on the behavior in XAML, e.g. EventName="MouseLeftButtonDown".
  2. If setting in code, assign EventName before the behavior is attached to the element.
  3. Check the behavior type named in the message to find the offending XAML element.

Example fix

// before
<behaviors:OnEventBehavior /> <!-- no EventName -->
// after
<behaviors:OnEventBehavior EventName="Click" />
Defensive patterns

Strategy: validation

Validate before calling

if (string.IsNullOrEmpty(OnEventBehavior.GetEventName(myBehavior)))
    throw new InvalidOperationException("EventName must be set before the behavior attaches.");

Type guard

static bool HasEventName(OnEventBehavior b) => !string.IsNullOrEmpty(b.EventName);

Try / catch

try
{
    element.Behaviors.Add(behavior);
}
catch (ArgumentException ex) when (ex.Message.Contains("EventName"))
{
    logger.Error(ex, "Behavior attached without EventName");
}

Prevention

When it happens

Trigger: Using a behavior derived from OnEventBehavior in XAML or code without setting the EventName property, e.g. <b:OnKeyUpBehavior/> with no EventName attribute.

Common situations: Copy-pasted XAML where the EventName attribute was dropped; renamed properties leaving EventName unset; creating the behavior programmatically without assigning EventName before attachment.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/0de7ad0a5862e150. Report an issue: GitHub.

Appendix: source

Thrown at sources/presentation/Stride.Core.Presentation.Wpf/Behaviors/OnEventBehavior.cs:67

        /// Gets or sets the type that owns the event when <see cref="EventName"/> describes a <see cref="RoutedEvent"/>.
        /// </summary>
        public Type EventOwnerType { get { return (Type)GetValue(EventOwnerTypeProperty); } set { SetValue(EventOwnerTypeProperty, value); } }

        /// <summary>
        /// Gets or sets whether to set the event as handled.
        /// </summary>
        public bool HandleEvent { get { return (bool)GetValue(HandleEventProperty); } set { SetValue(HandleEventProperty, value.Box()); } }

        /// <summary>
        /// Invoked when the monitored event is raised.
        /// </summary>
        protected abstract void OnEvent();

        /// <inheritdoc/>
        protected override void OnAttached()
        {
            if (EventName == null)
                throw new ArgumentException($"The EventName property must be set on behavior '{GetType().FullName}'.");

            var eventOwnerType = EventOwnerType ?? AssociatedObject.GetType();

            var uiElement = AssociatedObject as UIElement;

            var routedEvents = EventManager.GetRoutedEvents().Where(x => x.Name == EventName && x.OwnerType.IsAssignableFrom(eventOwnerType)).ToArray();

            if (uiElement != null && routedEvents.Length > 0)
            {
                if (routedEvents.Length > 1)
                    throw new NotImplementedException("TODO: several events found, find a way to decide the most relevant one.");

                routedEvent = routedEvents.First();
                uiElement.AddHandler(routedEvent, routedEventHandler);
            }
            else
            {
                var eventInfo = AssociatedObject.GetType().GetEvent(EventName);

View on GitHub (pinned to 96fad776d2)