stride3d/stride · error · InvalidOperationException
Behavior of type ' ' must be bound to objects of type ' '…
Error message
Behavior of type '{GetType()}' must be bound to objects of type '{typeof(FrameworkElement)}'. (currently bound to object typed '{AssociatedObject.GetType()}') What it means
The behavior subscribes to focus events and manipulates bindings via BindingOperations, which requires the associated object to be a FrameworkElement. If AssociatedObject cannot be cast to FrameworkElement, OnAttached throws InvalidOperationException explaining the required type and the actual type of the bound object.
Solutions
- Move the behavior to a FrameworkElement (e.g. the TextBox/Control itself) inside Interaction.Behaviors.
- If the target is inside a template, attach the behavior to the templated root FrameworkElement, not to a non-element node.
- Adjust code-behind attachment so the behavior is attached to a Control/FrameworkElement instance.
Example fix
<!-- before: behavior on a non-FrameworkElement node -->
<GradientStop>
<i:Interaction.Behaviors>
<b:OnFocusBindingInterruptionBehavior PropertyName="Color" Binding="{Binding Accent}" />
</i:Interaction.Behaviors>
</GradientStop>
<!-- after: attach to the hosting control -->
<TextBox Text="{Binding Accent}">
<i:Interaction.Behaviors>
<b:OnFocusBindingInterruptionBehavior PropertyName="Text" Binding="{Binding Accent}" />
</i:Interaction.Behaviors>
</TextBox> Defensive patterns
Strategy: type-guard
Validate before calling
if (!(associatedObject is FrameworkElement))
throw new InvalidOperationException($"Behavior requires a FrameworkElement; got {associatedObject?.GetType().Name}."); Type guard
static bool CanHostFocusBehavior(DependencyObject o) => o is FrameworkElement;
Try / catch
try { AttachBehavior(behavior, host); }
catch (InvalidOperationException ex) when (ex.Message.Contains("must be bound to objects of type")) { log.Error($"Move behavior to a FrameworkElement, not {host.GetType().Name}"); } Prevention
- Attach the behavior only inside FrameworkElement scopes (Controls, Panels, TextElements-derived elements).
- In templates, place Interaction.Behaviors on the templated root element, not on non-visual DependencyObjects.
- When wiring behaviors in code, type the host parameter as FrameworkElement to get compile-time safety.
When it happens
Trigger: Attaching OnFocusBindingInterruptionBehavior to a non-FrameworkElement such as a Freezable, BindingExpression target like a BindingMarker, a DependencyObject in a template that isn't an element, or collection items that are plain DependencyObjects.
Common situations: Dropping the behavior onto the wrong node in a template (e.g. on a GradientStop or a non-visual DependencyObject); using i:Interaction on objects where only triggers are legal; wiring the behavior in code to a generic DependencyObject.
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
- 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
- TODO: several events found, find a way to decide the most…
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/07a752d2bff63df0.
Report an issue: GitHub.
Appendix: source
Thrown at sources/presentation/Stride.Core.Presentation.Wpf/Behaviors/OnFocusBindingInterruptionBehavior.cs:54
throw new ArgumentException("PropertyName must be set.");
if (Binding == null)
{
throw new ArgumentException($"Binding must be set for {PropertyName} property of host '{AssociatedObject}' on behavior '{GetType().FullName}'.");
}
property = AssociatedObject.GetDependencyProperties(true).FirstOrDefault(dp => dp.Name == PropertyName);
if (property == null /* need to check DesignMode as well ? */)
throw new InvalidOperationException($"Impossible to find property named '{PropertyName}' on object typed '{AssociatedObject.GetType()}'.");
if ((Binding is Binding) == false)
throw new InvalidOperationException("Not supported binding type.");
var element = AssociatedObject as FrameworkElement;
if (element == null)
{
throw new InvalidOperationException(
$"Behavior of type '{GetType()}' must be bound to objects of type '{typeof(FrameworkElement)}'. (currently bound to object typed '{AssociatedObject.GetType()}')");
}
BindingOperations.SetBinding(AssociatedObject, property, Binding);
// subscribe to *Focus events
element.GotFocus += OnHostGotFocus;
element.LostFocus += OnHostLostFocus;
subscriber = new AnonymousDisposable(() =>
{
// unsubscribe from *Focus events
element.LostFocus -= OnHostLostFocus;
element.GotFocus -= OnHostGotFocus;
});
}
protected override void OnDetaching()View on GitHub (pinned to 96fad776d2)