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
- Ensure all children yielded to measure are visual children of the StackPanel (AddVisualChild if needed).
- Fix custom panel/control child enumeration to return only connected visuals.
- Avoid inserting elements from a different visual root; re-parent them first (remove from old parent before adding).
- 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
- Call RemoveVisualChild/Remove from old parent before re-parenting elements.
- Ensure custom controls report only connected visual children.
- Verify parent chains with VisualTreeHelper when reusing elements across trees.
- Never insert popup/window-owned elements directly into another subtree.
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
- SR.Visual_ArgumentOutOfRange
- ' ' is not a Visual or Visual3D.
- 0x80040206
- ArgumentNullException: child
- inverse ? SR.Visual_NotADescendant : SR.Visual_NotAnAncestor
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)