stride3d/stride · error · ArgumentException

Unable to find property

Error message

Unable to find property '{PropertyName}' on object of type '{AssociatedObject.GetType().FullName}'.

What it means

After confirming PropertyName is non-null, OnPropertyChangedCommandBehavior resolves it via GetDependencyProperties(true).FirstOrDefault(dp => dp.Name == PropertyName). If no dependency property with that exact name exists on the associated object, it throws ArgumentException reporting the property name and the object's type.

Solutions

  1. Set PropertyName to a dependency property that exists on the attached control's type (e.g. "IsChecked" for CheckBox/ToggleButton, "Text" for TextBox).
  2. Verify which element the behavior is attached to; move it or fix PropertyName if the wrong control type received it.
  3. Match casing exactly — dp.Name comparison is case-sensitive.
  4. For attached properties, use the registered name as dp.Name reports it.

Example fix

<!-- before: Button has no IsChecked property -->
<Button Command="{Binding Submit}">
  <i:Interaction.Behaviors>
    <b:OnPropertyChangedCommandBehavior PropertyName="IsChecked" Command="{Binding Submit}" />
  </i:Interaction.Behaviors>
</Button>

<!-- after -->
<CheckBox IsChecked="{Binding Accepted}">
  <i:Interaction.Behaviors>
    <b:OnPropertyChangedCommandBehavior PropertyName="IsChecked" Command="{Binding AcceptedChanged}" />
  </i:Interaction.Behaviors>
</CheckBox>
Defensive patterns

Strategy: validation

Validate before calling

bool ok = host.GetDependencyProperties(true).Any(dp => dp.Name == behavior.PropertyName);
if (!ok) throw new InvalidOperationException($"{host.GetType().Name} has no dependency property '{behavior.PropertyName}'.");

Type guard

static bool HasDependencyProperty(DependencyObject o, string name) =>
    o?.GetDependencyProperties(true).Any(dp => dp.Name == name) == true;

Try / catch

try { AttachBehavior(behavior, host); }
catch (ArgumentException ex) when (ex.Message.StartsWith("Unable to find property")) { log.Error($"Wrong PropertyName '{behavior.PropertyName}' for {host.GetType().Name}"); }

Prevention

When it happens

Trigger: Attaching the behavior to a Button but setting PropertyName="IsChecked" (a ToggleButton property); case mismatch like PropertyName="ischecked"; attaching to a control type that doesn't expose the named dependency property; targeting a CLR-only property.

Common situations: Re-using a behavior XAML snippet across different controls without updating PropertyName; refactoring a control and renaming its dependency property; attaching the behavior in a shared style applied to multiple unrelated control types.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at sources/presentation/Stride.Core.Presentation.Wpf/Behaviors/OnPropertyChangedCommandBehavior.cs:80

        /// <summary>
        /// Gets or set whether the command should be executed only when the source of the binding associated to the dependency property is updated.
        /// </summary>
        /// <remarks>If set to <c>true</c>, this property requires that a binding exists on the dependency property and that it has <see cref="Binding.NotifyOnSourceUpdated"/> set to <c>true</c>.</remarks>
        public bool ExecuteOnlyOnSourceUpdate { get { return (bool)GetValue(ExecuteOnlyOnSourceUpdateProperty); } set { SetValue(ExecuteOnlyOnSourceUpdateProperty, value.Box()); } }
        
        /// <summary>
        /// Gets or sets whether the value of the property should be used as the parameter of the command to execute when the property is modified.
        /// </summary>
        public bool PassValueAsParameter { get { return (bool)GetValue(PassValueAsParameterProperty); } set { SetValue(PassValueAsParameterProperty, value.Box()); } }

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

            dependencyProperty = AssociatedObject.GetDependencyProperties(true).FirstOrDefault(dp => dp.Name == PropertyName);
            if (dependencyProperty == null)
                throw new ArgumentException($"Unable to find property '{PropertyName}' on object of type '{AssociatedObject.GetType().FullName}'.");

            propertyWatcher.Attach(AssociatedObject);
            // TODO: Register/Unregister handlers when the PropertyName changes
            propertyWatcher.RegisterValueChangedHandler(dependencyProperty, OnPropertyChanged);
            Binding.AddSourceUpdatedHandler(AssociatedObject, OnSourceUpdated);
        }

        protected override void OnDetaching()
        {
            propertyWatcher.Detach();
            base.OnDetaching();
        }

        private void OnSourceUpdated(object sender, [NotNull] DataTransferEventArgs e)
        {
            if (ExecuteOnlyOnSourceUpdate && e.Property == dependencyProperty)
            {
                ExecuteCommand();

View on GitHub (pinned to 96fad776d2)