stride3d/stride · error · InvalidOperationException

A part named 'PART_IncreaseButton' must be present in the…

Error message

A part named 'PART_IncreaseButton' must be present in the ControlTemplate, and must be of type 'RepeatButton'.

What it means

NumericTextBox.OnApplyTemplate requires the template part 'PART_IncreaseButton' of type RepeatButton so it can wire step-up behavior. If the applied ControlTemplate lacks this named part (or it is not a RepeatButton), GetTemplateChild yields null and an InvalidOperationException is thrown.

Solutions

  1. Add a RepeatButton named PART_IncreaseButton to the ControlTemplate
  2. Verify exact part name 'PART_IncreaseButton' (case-sensitive)
  3. Ensure the element type is RepeatButton (needed for auto-repeat while pressed)
  4. Start from the default NumericTextBox template and modify rather than rewrite

Example fix

<!-- before -->
<ControlTemplate TargetType="ntb:NumericTextBox">
  <ScrollViewer x:Name="PART_ContentHost"/>
</ControlTemplate>
<!-- after -->
<ControlTemplate TargetType="ntb:NumericTextBox">
  <Grid>
    <ScrollViewer x:Name="PART_ContentHost"/>
    <RepeatButton x:Name="PART_IncreaseButton"/>
    <RepeatButton x:Name="PART_DecreaseButton"/>
  </Grid>
</ControlTemplate>
Defensive patterns

Strategy: validation

Validate before calling

var btn = numericTextBox.Template?.FindName("PART_IncreaseButton", numericTextBox) as RepeatButton;
if (btn == null) throw new InvalidOperationException("NumericTextBox template missing PART_IncreaseButton (RepeatButton)");

Type guard

bool HasIncreaseButton(NumericTextBox c) => c.Template?.FindName("PART_IncreaseButton", c) is RepeatButton;

Try / catch

try { control.ApplyTemplate(); }
catch (InvalidOperationException ex) { log.Error(ex, "Invalid NumericTextBox template; restoring default style"); control.Style = null; }

Prevention

When it happens

Trigger: Applying a custom Style/ControlTemplate for NumericTextBox without a RepeatButton named PART_IncreaseButton; mistyping the part name; using a Button instead of RepeatButton.

Common situations: Re-skinning numeric editors; copying templates from older library versions after part renames; stripping 'unused' spinner buttons from a template.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at sources/presentation/Stride.Core.Presentation.Wpf/Controls/NumericTextBox.cs:267

        /// <summary>
        /// Raised when one of the repeat button is pressed.
        /// </summary>
        public event EventHandler<RepeatButtonPressedRoutedEventArgs> RepeatButtonPressed { add { AddHandler(RepeatButtonPressedEvent, value); } remove { RemoveHandler(RepeatButtonPressedEvent, value); } }

        /// <summary>
        /// Raised when one of the repeat button is released.
        /// </summary>
        public event EventHandler<RepeatButtonPressedRoutedEventArgs> RepeatButtonReleased { add { AddHandler(RepeatButtonReleasedEvent, value); } remove { RemoveHandler(RepeatButtonReleasedEvent, value); } }

        /// <inheritdoc/>
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            increaseButton = GetTemplateChild("PART_IncreaseButton") as RepeatButton;
            if (increaseButton == null)
                throw new InvalidOperationException("A part named 'PART_IncreaseButton' must be present in the ControlTemplate, and must be of type 'RepeatButton'.");

            decreaseButton = GetTemplateChild("PART_DecreaseButton") as RepeatButton;
            if (decreaseButton == null)
                throw new InvalidOperationException("A part named 'PART_DecreaseButton' must be present in the ControlTemplate, and must be of type 'RepeatButton'.");

            contentHost = GetTemplateChild("PART_ContentHost") as ScrollViewer;
            if (contentHost == null)
                throw new InvalidOperationException("A part named 'PART_ContentHost' must be present in the ControlTemplate, and must be of type 'ScrollViewer'.");

            var increasePressedWatcher = new DependencyPropertyWatcher(increaseButton);
            increasePressedWatcher.RegisterValueChangedHandler(ButtonBase.IsPressedProperty, RepeatButtonIsPressedChanged);
            var decreasePressedWatcher = new DependencyPropertyWatcher(decreaseButton);
            decreasePressedWatcher.RegisterValueChangedHandler(ButtonBase.IsPressedProperty, RepeatButtonIsPressedChanged);
            var textValue = FormatValue(Value);

            SetCurrentValue(TextProperty, textValue);
        }

View on GitHub (pinned to 96fad776d2)