stride3d/stride · error · ArgumentException

The PropertyName property must be set on behavior

Error message

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

What it means

OnPropertyChangedCommandBehavior watches a named dependency property on the associated object and invokes a Command whenever it changes. OnAttached first requires PropertyName to be non-null; if it was never set, it throws ArgumentException naming the behavior type. Note it checks only for null, not empty strings.

Solutions

  1. Set PropertyName on the behavior to the dependency property to watch, e.g. PropertyName="IsChecked".
  2. If configured in code, assign PropertyName before attaching the behavior to the element.
  3. If PropertyName comes from data, ensure it is available at attach time or set it directly in XAML.

Example fix

<!-- before -->
<CheckBox IsChecked="{Binding Enabled}">
  <i:Interaction.Behaviors>
    <b:OnPropertyChangedCommandBehavior Command="{Binding EnabledChanged}" />
  </i:Interaction.Behaviors>
</CheckBox>

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

Strategy: validation

Validate before calling

if (behavior.PropertyName == null)
    throw new InvalidOperationException("OnPropertyChangedCommandBehavior requires PropertyName before attach.");

Try / catch

try { AttachBehavior(behavior, host); }
catch (ArgumentException ex) when (ex.Message.Contains("The PropertyName property must be set")) { log.Error("Behavior misconfigured: PropertyName is null"); }

Prevention

When it happens

Trigger: Using <b:OnPropertyChangedCommandBehavior Command="{Binding MyCommand}"/> without a PropertyName attribute; constructing the behavior in code without assigning PropertyName; a bound/templated value for PropertyName that is null at attach time.

Common situations: Copy-pasting behavior XAML and deleting the PropertyName attribute; wiring the behavior through a style where only Command is set; dynamic configuration where PropertyName comes from a ViewModel property that isn't populated yet when the element loads.

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/6f8be13beb6f9886. Report an issue: GitHub.

Appendix: source

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

        /// Gets or sets the parameter of the command to execute when the property is modified.
        /// </summary>
        public object CommandParameter { get { return GetValue(CommandParameterProperty); } set { SetValue(CommandParameterProperty, value); } }

        /// <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)

View on GitHub (pinned to 96fad776d2)