stride3d/stride · error · InvalidOperationException

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

Error message

A part named '{ListBoxPartName}' must be present in the ControlTemplate, and must be of type '{nameof(ListBox)}'.

What it means

SearchComboBox.OnApplyTemplate also requires a ListBox part (ListBoxPartName) that hosts filtered results. If the applied ControlTemplate omits it or substitutes another element type, GetTemplateChild returns null and an InvalidOperationException is thrown before the control finishes wiring its event handlers.

Solutions

  1. Add a ListBox named per ListBoxPartName (typically PART_ListBox) to the ControlTemplate
  2. Keep the exact, case-sensitive part name
  3. Use a ListBox specifically — MouseUp handling is attached to it
  4. Start from the default SearchComboBox template and modify incrementally

Example fix

<!-- before -->
<ControlTemplate TargetType="scb:SearchComboBox">
  <Grid>
    <TextBox x:Name="PART_EditableTextBox"/>
    <ItemsControl x:Name="PART_ListBox"/>
  </Grid>
</ControlTemplate>
<!-- after -->
<ControlTemplate TargetType="scb:SearchComboBox">
  <Grid>
    <TextBox x:Name="PART_EditableTextBox"/>
    <ListBox x:Name="PART_ListBox"/>
  </Grid>
</ControlTemplate>
Defensive patterns

Strategy: validation

Validate before calling

var lb = searchComboBox.Template?.FindName("PART_ListBox", searchComboBox) as ListBox;
if (lb == null) throw new InvalidOperationException("SearchComboBox template missing ListBox part");

Type guard

bool HasResultsList(SearchComboBox c) => c.Template?.FindName("PART_ListBox", c) is ListBox;

Try / catch

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

Prevention

When it happens

Trigger: Custom ControlTemplate for SearchComboBox without a ListBox named per ListBoxPartName; part renamed or replaced by ItemsControl/ListView.

Common situations: Re-templating search combos; partial copies of the default template; designers replacing ListBox with lighter list controls, breaking the required part contract.

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

Appendix: source

Thrown at sources/presentation/Stride.Core.Presentation.Wpf/Controls/SearchComboBox.cs:155

        /// Gets or sets the search text of this <see cref="SearchComboBox"/>
        /// </summary>
        public string SearchText { get { return (string)GetValue(SearchTextProperty); } set { SetValue(SearchTextProperty, value); } }
        /// <summary>
        /// Gets or sets the content to display when the TextBox is empty.
        /// </summary>
        public object WatermarkContent { get { return GetValue(WatermarkContentProperty); } set { SetValue(WatermarkContentProperty, value); } }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            editableTextBox = GetTemplateChild(EditableTextBoxPartName) as TextBox;
            if (editableTextBox == null)
                throw new InvalidOperationException($"A part named '{EditableTextBoxPartName}' must be present in the ControlTemplate, and must be of type '{typeof(TextBox).FullName}'.");

            listBox = GetTemplateChild(ListBoxPartName) as ListBox;
            if (listBox == null)
                throw new InvalidOperationException($"A part named '{ListBoxPartName}' must be present in the ControlTemplate, and must be of type '{nameof(ListBox)}'.");
            
            editableTextBox.LostFocus += EditableTextBoxLostFocus;
            editableTextBox.PreviewKeyDown += EditableTextBoxPreviewKeyDown;
            editableTextBox.PreviewKeyUp += EditableTextBoxPreviewKeyUp;
            editableTextBox.Validated += EditableTextBoxValidated;
            listBox.MouseUp += ListBoxMouseUp;
        }

        protected override void OnGotKeyboardFocus(KeyboardFocusChangedEventArgs e)
        {
            base.OnGotKeyboardFocus(e);
            if (OpenDropDownOnFocus && !listBoxClicking)
            {
                IsDropDownOpen = true;
            }
            listBoxClicking = false;
        }

View on GitHub (pinned to 96fad776d2)