dotnet/wpf · error · ArgumentException

SR.Stack_VisualInDifferentSubTree

Error message

SR.Stack_VisualInDifferentSubTree

What it means

StackPanel.MeasureOverride walks up the visual tree from a child to verify it belongs to the same visual subtree as the panel. If VisualTreeHelper.GetParent returns null before reaching the panel itself, the child is in a different visual subtree, and an ArgumentException (Stack_VisualInDifferentSubTree) is thrown for the child parameter.

Solutions

  1. Ensure all children yielded to measure are visual children of the StackPanel (AddVisualChild if needed).
  2. Fix custom panel/control child enumeration to return only connected visuals.
  3. Avoid inserting elements from a different visual root; re-parent them first (remove from old parent before adding).
  4. Reproduce in a minimal sample and check the parent chain with VisualTreeHelper.GetParent before measure.

Example fix

// before
panel.Children.Add(elementFromOtherWindow); // still parented elsewhere
// after
((Panel)elementFromOtherWindow.Parent).Children.Remove(elementFromOtherWindow);
panel.Children.Add(elementFromOtherWindow);
Defensive patterns

Strategy: type-guard

Validate before calling

bool inSameSubtree = false;
DependencyObject p = child;
while (p != null) { if (p == panel) { inSameSubtree = true; break; } p = VisualTreeHelper.GetParent(p); }
if (!inSameSubtree) throw new ArgumentException("child not in panel's visual subtree");

Type guard

bool IsVisualDescendant(DependencyObject child, DependencyObject ancestor) {
  for (var p = child; p != null; p = VisualTreeHelper.GetParent(p))
    if (p == ancestor) return true;
  return false;
}

Prevention

When it happens

Trigger: A UIElement reports a child that is not actually its visual descendant — typically with custom panels/elements that yield children not connected to the StackPanel's visual tree, or elements whose visual parent chain is broken/re-parented during measure.

Common situations: Custom controls overriding GetVisualChildren incorrectly; attaching elements created in a different visual root (popup/window) into a StackPanel's measure pass; virtualization/custom layout bugs where children are temporarily disconnected.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/253d003b05d13c3d. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/Stack.cs:852

                    : ((UIElement)children[i]).DesiredSize.Height;
            }

            return physicalOffset;
        }

        private int FindChildIndexThatParentsVisual(Visual child)
        {
            DependencyObject dependencyObjectChild = child;

            DependencyObject parent = VisualTreeHelper.GetParent(child);

            while (parent != this)
            {
                dependencyObjectChild = parent;
                parent = VisualTreeHelper.GetParent(dependencyObjectChild);
                if (parent == null)
                {
                    throw new ArgumentException(SR.Stack_VisualInDifferentSubTree,nameof(child));
                }
            }

            UIElementCollection children = this.Children;
            //The Downcast is ok because StackPanel's
            //child has to be a UIElement to be in this.Children collection
            return (children.IndexOf((UIElement)dependencyObjectChild));
        }

        private void MakeVisiblePhysicalHelper(Rect r, ref Vector newOffset, ref Rect newRect)
        {
            double viewportOffset;
            double viewportSize;
            double targetRectOffset;
            double targetRectSize;
            double minPhysicalOffset;

            bool fHorizontal = (Orientation == Orientation.Horizontal);

View on GitHub (pinned to 81131a70a4)