stride3d/stride · error · InvalidOperationException

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

Error message

A part named '{GridPartName}' must be present in the ControlTemplate, and must be of type '{typeof(Grid).FullName}'.

What it means

CanvasView.OnApplyTemplate retrieves the mandatory template part named by GridPartName and requires it to be a Grid, storing it to host the rendering canvas. If GetTemplateChild returns null or a non-Grid, the control cannot function and throws InvalidOperationException. This enforces the control/template contract for custom templates.

Solutions

  1. Add a Grid named with GridPartName ('PART_Grid'-style key) inside the custom ControlTemplate.
  2. Ensure the element with that name is of type Grid, not another panel.
  3. Start from the default template in the theme dictionary and modify without removing the named part.

Example fix

<!-- before: custom template missing part -->
<ControlTemplate TargetType="controls:CanvasView">
  <Border/>
</ControlTemplate>
<!-- after -->
<ControlTemplate TargetType="controls:CanvasView">
  <Grid x:Name="PART_Grid"/>
</ControlTemplate>
Defensive patterns

Strategy: validation

Validate before calling

var grid = control.Template?.FindName("PART_Grid", control) as Grid;
if (grid == null) throw new InvalidOperationException("Custom CanvasView template lacks the required Grid part.");

Type guard

bool HasGridPart(CanvasView view) => view.Template?.FindName("PART_Grid", view) is Grid;

Try / catch

try { control.ApplyTemplate(); }
catch (InvalidOperationException ex) { log.Error("CanvasView template invalid", ex); }

Prevention

When it happens

Trigger: Applying a ControlTemplate for CanvasView that lacks the required named Grid part, names it differently, or hosts an element of another type (e.g. Border) under that name.

Common situations: Restyling CanvasView with a custom template based on a generic.xaml copy that was edited; renaming the part; template not yet applied when code runs.

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

Appendix: source

Thrown at sources/presentation/Stride.Core.Presentation.Wpf/Controls/CanvasView/CanvasView.cs:101

        {
            var view = (CanvasView)sender;

            var model = e.OldValue as IDrawingModel;
            model?.Detach(view);

            model = e.NewValue as IDrawingModel;
            model?.Attach(view);

            view.InvalidateDrawing();
        }

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

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

            var canvas = new Canvas();
            grid.Children.Add(canvas);
            canvas.UpdateLayout();
            renderer = new CanvasRenderer(canvas);
        }

        protected override Size ArrangeOverride(Size arrangeBounds)
        {
            if (ActualWidth > 0 && ActualHeight > 0)
            {
                if (Interlocked.CompareExchange(ref this.isDrawingInvalidated, 0, 1) == 1)
                {
                    UpdateVisuals();
                }
            }

            return base.ArrangeOverride(arrangeBounds);

View on GitHub (pinned to 96fad776d2)