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
- Add a RepeatButton named PART_IncreaseButton to the ControlTemplate
- Verify exact part name 'PART_IncreaseButton' (case-sensitive)
- Ensure the element type is RepeatButton (needed for auto-repeat while pressed)
- 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
- Keep all PART_ elements (Increase, Decrease, ContentHost) when re-skinning
- Use RepeatButton, not Button, for spinner parts
- Diff your template against the default after upgrades
- Force ApplyTemplate in tests to catch missing parts early
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
- A part named ' ' must be present in the ControlTemplate…
- A part named ' ' must be present in the ControlTemplate…
- A part named ' ' must be present in the ControlTemplate…
- A part named 'PART_ContentHost' must be present in the…
- A part named 'PART_DecreaseButton' must be present in the…
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)