stride3d/stride · error · InvalidOperationException

Unable to reach the VirtualizingTilePanel of the associated…

Error message

Unable to reach the VirtualizingTilePanel of the associated ItemsControl.

What it means

After locating the ItemsPresenter, GetItemsPanel expects its first visual child to be a VirtualizingTilePanel. If the child at index 0 is null (or not that panel type), the cast/check throws InvalidOperationException because thumbnail prioritization requires Stride's custom virtualizing panel.

Solutions

  1. Set the ItemsPanel template to Stride's VirtualizingTilePanel: <ItemsPanelTemplate><vt:VirtualizingTilePanel/></ItemsPanelTemplate>
  2. Wait for panel realization (generator status / Loaded) before calling GetItemsPanel
  3. Search recursively among the presenter's children instead of assuming child index 0

Example fix

// before
<ItemsControl.ItemsPanel>
  <ItemsPanelTemplate><VirtualizingStackPanel/></ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
// after
<ItemsControl.ItemsPanel>
  <ItemsPanelTemplate><stride:VirtualizingTilePanel/></ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
Defensive patterns

Strategy: validation

Validate before calling

var presenter = itemsControl.FindVisualChildOfType<ItemsPresenter>();
var panel = presenter != null ? VisualTreeHelper.GetChild(presenter, 0) as VirtualizingTilePanel : null;
if (panel == null) return; // wrong ItemsPanel or not realized

Type guard

static bool HasVirtualizingTilePanel(ItemsPresenter p) => p != null && VisualTreeHelper.GetChild(p, 0) is VirtualizingTilePanel;

Try / catch

try { var panel = GetItemsPanel(itemsControl); }
catch (InvalidOperationException) { log.Warn("ItemsPanel is not VirtualizingTilePanel"); }

Prevention

When it happens

Trigger: The ItemsControl's ItemsPanel is not (or does not wrap) a VirtualizingTilePanel — e.g. default VirtualizingStackPanel/WrapPanel, or VisualTreeHelper.GetChild(itemsPresenter, 0) returns null before panel realization.

Common situations: Using the behavior with a standard ItemsControl template whose panel is not VirtualizingTilePanel; panel realized later than the behavior's loaded hook.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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

Appendix: source

Thrown at sources/editor/Stride.Core.Assets.Editor/View/Behaviors/TilePanelThumbnailPrioritizationBehavior.cs:60

            if (items == null || firstVisibleItemIndex > lastVisibleItemIndex)
                return;

            var session = items[0].Session;
            var visibleAssets = items.Subset(firstVisibleItemIndex, lastVisibleItemIndex - firstVisibleItemIndex + 1).OfType<AssetViewModel>();
            session.Thumbnails.IncreaseThumbnailPriority(visibleAssets);
        }

        private static VirtualizingTilePanel GetItemsPanel(DependencyObject itemsControl)
        {
            var itemsPresenter = itemsControl.FindVisualChildOfType<ItemsPresenter>();

            if (itemsPresenter == null)
                throw new InvalidOperationException("Unable to reach the ItemsPresenter of the associated ItemsControl.");

            var itemsPanel = (VirtualizingTilePanel)VisualTreeHelper.GetChild(itemsPresenter, 0);

            if (itemsPanel == null)
                throw new InvalidOperationException("Unable to reach the VirtualizingTilePanel of the associated ItemsControl.");
            return itemsPanel;
        }
    }
}

View on GitHub (pinned to 96fad776d2)