stride3d/stride · error · InvalidOperationException

The given element is not a child of this panel.

Error message

The given element is not a child of this panel.

What it means

PanelViewModel.ChangeChildElementLayoutProperties reorders a child inside its parent panel and throws this InvalidOperationException when collection.IndexOf(child) returns -1, i.e. the given element is not among the panel's Children. Reordering (MoveUp/MoveDown) is impossible without a valid current index.

Solutions

  1. Verify the child is in AssetSidePanel.Children before invoking the layout command.
  2. Resolve the child's actual parent panel at dispatch time instead of caching it.
  3. Disable or skip move commands for root-level elements without a panel parent.
  4. Refresh selection/parent references after undo/redo or reparenting.

Example fix

// before
panelViewModel.ChangeChildElementLayoutProperties(child, PanelCommandMode.MoveUp);
// after
if (panelViewModel.AssetSidePanel.Children.Contains(child.GetUIElement()))
    panelViewModel.ChangeChildElementLayoutProperties(child, PanelCommandMode.MoveUp);
Defensive patterns

Strategy: validation

Validate before calling

if (!panelViewModel.AssetSidePanel.Children.Contains(child.GetUIElement())) return; // not a child of this panel

Type guard

bool IsChildOfPanel(PanelViewModel panel, UIElementViewModel child) => panel.AssetSidePanel.Children.Contains(child.GetUIElement());

Try / catch

try { panel.ChangeChildElementLayoutProperties(child, mode); }
catch (InvalidOperationException ex) when (ex.Message.Contains("not a child of this panel")) {
    // re-resolve the child's actual parent panel and retry there
}

Prevention

When it happens

Trigger: Calling ChangeChildElementLayoutProperties with a child belonging to a different panel, an element already removed, or a root-level element with no panel parent; move commands dispatched against the wrong/previous panel view model.

Common situations: Move up/down commands routed to a stale selection after the element was reparented, batch layout scripts assuming the child is still in the same panel, undo/redo leaving stale parent references.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


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

Appendix: source

Thrown at sources/editor/Stride.Assets.Presentation/AssetEditors/UIEditor/ViewModels/PanelViewModel.cs:189

                        default:
                            throw new ArgumentException($"{mode} is not a supported mode.", nameof(mode));
                    }

                    var currentValue = GetDependencyPropertyValue(child, propertyKey);
                    var newValue = Math.Max(0, currentValue + offset);
                    SetDependencyPropertyValue(child, propertyKey, newValue);
                    Editor.UndoRedoService.SetName(transaction, $"Move {UIEditorBaseViewModel.GetDisplayName(child)}");
                    return;
                }

                var stackPanel = AssetSidePanel as StackPanel;
                if (stackPanel != null)
                {
                    var collection = AssetSidePanel.Children;
                    var index = collection.IndexOf(child);
                    if (index == -1)
                        throw new InvalidOperationException("The given element is not a child of this panel.");

                    int newIndex;
                    switch (mode)
                    {
                        case PanelCommandMode.MoveDown:
                            newIndex = index + 1;
                            if (newIndex >= collection.Count)
                                return;
                            break;

                        case PanelCommandMode.MoveUp:
                            newIndex = index - 1;
                            if (newIndex < 0)
                                return;
                            break;

                        default:
                            throw new ArgumentException($"{mode} is not a supported mode.", nameof(mode));

View on GitHub (pinned to 96fad776d2)