stride3d/stride · error · InvalidOperationException
Unable to find a parent Selector to the associated…
Error message
Unable to find a parent Selector to the associated VirtualizingTilePanel.
What it means
TilePanelNavigationBehavior maps keyboard arrow-key navigation onto a Selector that hosts a VirtualizingTilePanel. In OnAttachedAndLoaded it walks the visual tree upward from the panel to find an ancestor of type Selector; if the walk reaches null without finding one, it throws InvalidOperationException since the behavior has no selector to synchronize and configure.
Solutions
- Place the VirtualizingTilePanel inside a Selector-derived control, e.g. <ListBox ItemsPanel> containing the panel as ItemsPanel.
- If selection is not desired, set the ListBox to disable selection visually rather than switching to ItemsControl, or remove this behavior.
- Ensure the behavior attaches after the panel is in the visual tree under the selector (check OnAttachedAndLoaded conditions and re-parenting timing).
Example fix
<!-- before: panel not inside a Selector -->
<ItemsControl ItemsSource="{Binding Items}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<wpf:VirtualizingTilePanel>
<i:Interaction.Behaviors>
<b:TilePanelNavigationBehavior />
</i:Interaction.Behaviors>
</wpf:VirtualizingTilePanel>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
<!-- after -->
<ListBox ItemsSource="{Binding Items}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<wpf:VirtualizingTilePanel>
<i:Interaction.Behaviors>
<b:TilePanelNavigationBehavior />
</i:Interaction.Behaviors>
</wpf:VirtualizingTilePanel>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox> Defensive patterns
Strategy: validation
Validate before calling
DependencyObject WalkUpForSelector(DependencyObject start)
{
var parent = LogicalTreeHelper.GetParent(start) ?? VisualTreeHelper.GetParent(start);
while (parent != null && !(parent is System.Windows.Controls.Primitives.Selector))
parent = LogicalTreeHelper.GetParent(parent) ?? VisualTreeHelper.GetParent(parent);
return parent;
}
// before attach: if (WalkUpForSelector(tilePanel) == null) log.Warn("TilePanelNavigationBehavior requires a Selector ancestor"); Type guard
static bool HasSelectorAncestor(DependencyObject o) => WalkUpForSelector(o) is System.Windows.Controls.Primitives.Selector;
Try / catch
try { AttachBehavior(behavior, tilePanel); }
catch (InvalidOperationException ex) when (ex.Message.Contains("parent Selector")) { log.Error("Place VirtualizingTilePanel inside a ListBox/ListView or another Selector"); } Prevention
- Always host VirtualizingTilePanel as the ItemsPanel of a Selector-derived control when using this behavior.
- Avoid ItemsControl for this panel if keyboard navigation via the behavior is required.
- Re-check ancestor chain after any template re-parenting that moves the panel.
When it happens
Trigger: Attaching TilePanelNavigationBehavior to a VirtualizingTilePanel that is NOT placed inside a ListBox/ListView/ComboBox/other Selector — e.g. used directly inside a Grid, ItemsControl, or ContentControl; detaching/re-parenting the panel so its ancestor chain is broken at load time.
Common situations: Using VirtualizingTilePanel standalone for layout and adding the navigation behavior anyway; wrapping the panel in an ItemsControl instead of a ListBox because no selection is wanted; template restructuring that moved the panel outside the Selector subtree before the behavior 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
- A dependency object is already attached to this instance of…
- A dependency object must be attached in order to register a…
- A dependency object must be attached in order to unregister…
- A dispatcher lock must be created from a different thread…
- A part named ' ' must be present in the ControlTemplate…
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/538903636632fa50.
Report an issue: GitHub.
Appendix: source
Thrown at sources/presentation/Stride.Core.Presentation.Wpf/Behaviors/TilePanelNavigationBehavior.cs:30
namespace Stride.Core.Presentation.Behaviors
{
public class TilePanelNavigationBehavior : DeferredBehaviorBase<VirtualizingTilePanel>
{
private Selector selector;
protected override void OnAttachedAndLoaded()
{
DependencyObject parent = AssociatedObject;
while (parent != null)
{
parent = VisualTreeHelper.GetParent(parent);
if (parent is Selector)
break;
}
if (parent == null)
{
throw new InvalidOperationException("Unable to find a parent Selector to the associated VirtualizingTilePanel.");
}
selector = (Selector)parent;
selector.IsSynchronizedWithCurrentItem = true;
KeyboardNavigation.SetDirectionalNavigation(selector, KeyboardNavigationMode.None);
selector.PreviewKeyDown += OnAssociatedObjectKeyDown;
}
protected override void OnDetachingAndUnloaded()
{
if (selector != null)
selector.PreviewKeyDown -= OnAssociatedObjectKeyDown;
selector = null;
}
private void OnAssociatedObjectKeyDown(object sender, [NotNull] KeyEventArgs e)View on GitHub (pinned to 96fad776d2)