stride3d/stride · error · NotImplementedException
TODO: several events found, find a way to decide the most…
Error message
TODO: several events found, find a way to decide the most relevant one.
What it means
OnEventBehavior.OnAttached throws NotImplementedException when more than one routed event with the same name matches the event owner type. The library cannot decide which routed event is the most relevant to subscribe to. This is an intentional unfinished-code guard, not an expected runtime condition.
Solutions
- Use a more specific EventName that does not collide with other routed events.
- Set EventOwnerType explicitly to disambiguate which owning type's event should be used.
- Avoid attaching the behavior to the UIElement path; use the CLR-event path instead.
- Patch the library to pick the closest owner type in the hierarchy.
Example fix
// before
<behaviors:OnEventBehavior EventName="Changed" /> <!-- ambiguous routed event -->
// after
<behaviors:OnEventBehavior EventName="Changed" EventOwnerType="{x:Type local:MyControl}" /> Defensive patterns
Strategy: fallback
Validate before calling
var matches = EventManager.GetRoutedEvents()
.Where(x => x.Name == eventName && x.OwnerType.IsAssignableFrom(ownerType)).ToArray();
if (matches.Length > 1)
logger.Warn($"EventName '{eventName}' is ambiguous: {matches.Length} routed events match."); Type guard
static bool IsUnambiguousRoutedEvent(string eventName, Type ownerType) =>
EventManager.GetRoutedEvents().Count(x => x.Name == eventName && x.OwnerType.IsAssignableFrom(ownerType)) == 1; Try / catch
try
{
element.Behaviors.Add(behavior);
}
catch (NotImplementedException ex) when (ex.Message.Contains("several events"))
{
logger.Error(ex, $"Ambiguous routed event '{behavior.EventName}'; set EventOwnerType");
} Prevention
- Set EventOwnerType explicitly when the event name may be ambiguous.
- Choose EventName values unique across base and attached event classes.
- Avoid custom routed event names that collide with built-in WPF events.
When it happens
Trigger: Attaching the behavior to a UIElement when EventManager.GetRoutedEvents() contains multiple RoutedEvents with the same Name whose OwnerType is assignable from the event owner type (e.g. name collision across class hierarchies).
Common situations: Custom or third-party controls defining routed events whose names clash with built-in WPF events; using an ambiguous EventName that exists on both a base class and an attached class.
Related errors
- This behavior must be attached to an instance of…
- The OnComboBoxClosedWithSelectionBehavior must be attached…
- The OnSelectionChangedWithSelectionBehavior must be…
- The EventName property must be set on behavior
- Impossible to find a valid event named
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/bf56bc32082f6a46.
Report an issue: GitHub.
Appendix: source
Thrown at sources/presentation/Stride.Core.Presentation.Wpf/Behaviors/OnEventBehavior.cs:78
/// </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);
if (eventInfo == null)
throw new InvalidOperationException($"Impossible to find a valid event named '{EventName}'.");
eventHandler = AnonymousEventHandler.RegisterEventHandler(eventInfo, AssociatedObject, OnEvent);
}
}
/// <inheritdoc/>
protected override void OnDetaching()
{View on GitHub (pinned to 96fad776d2)