dotnet/wpf · error · ArgumentException
SR.VisualCollection_VisualHasParent
Error message
SR.VisualCollection_VisualHasParent
What it means
Thrown by the VisualCollection indexer setter (and Add) when the visual being inserted already has a parent (_parent != null) or is the root element of a visual target (IsRootElement). A Visual can belong to exactly one visual tree, so WPF refuses to attach an already-parented visual rather than silently re-parenting it.
Solutions
- Remove the visual from its current parent's collection before adding it to the new one.
- Create a new instance for the second location instead of sharing one visual.
- For cross-tree display, use separate visuals or HwndHost/VisualTarget patterns that don't require dual parenting.
- Guard with VisualTreeHelper.GetParent(v) == null && !v.IsRootElement before adding.
Example fix
// before // sharedBorder currently inside panelA panelB.Children.Add(sharedBorder); // ArgumentException: VisualHasParent // after panelA.Children.Remove(sharedBorder); panelB.Children.Add(sharedBorder);
Defensive patterns
Strategy: validation
Validate before calling
if (VisualTreeHelper.GetParent(visual) != null || visual.IsRootElement)
throw new InvalidOperationException("Detach the visual before re-parenting");
collection[index] = visual; Type guard
static bool IsOrphanVisual(Visual v) => VisualTreeHelper.GetParent(v) == null && !v.IsRootElement;
Try / catch
try { collection.Add(visual); }
catch (ArgumentException) { /* visual already has a parent or is a root */ } Prevention
- Remove before Add whenever moving a visual between containers.
- Check VisualTreeHelper.GetParent(v) before attaching.
- Treat IsRootElement visuals as unattachable.
- Prefer creating fresh visuals over reparenting shared ones.
When it happens
Trigger: collection[index] = v or collection.Add(v) where v._parent is non-null (v is a child of another Visual) or v.IsRootElement is true (v is the root of a VisualTarget/host hierarchy).
Common situations: Reusing one visual instance across multiple containers (movement between Grids/Panels without removal); adding a VisualTarget root visual into a normal children collection; forgetting that Remove must precede Add when moving a control.
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.VisualCollection_EntryInUse
- SR.Collection_BadRank
- " }} " element found. Expected fixed page element ( }} ).
- ' ' ContentType is not valid.
- ' ' ID is not a valid XSD ID.
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/09922a1cd78c9850.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/VisualCollection.cs:342
ArgumentOutOfRangeException.ThrowIfNegative(index);
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual(index, _size);
Visual child = _items[index];
if ((value == null) && (child != null))
{
DisconnectChild(index);
}
else if (value != null)
{
if (child != null)
{
throw new System.ArgumentException(SR.VisualCollection_EntryInUse);
}
if ((value._parent != null) // Only a visual that isn't a visual parent or
|| value.IsRootElement) // are a root node of a visual target can be set into the collection.
{
throw new System.ArgumentException(SR.VisualCollection_VisualHasParent);
}
ConnectChild(index, value);
}
}
}
/// <summary>
/// Sets the specified visual at the specified index into the child
/// collection. It also corrects the parent.
/// Note that the function requires that _item[index] == null and it
/// also requires that the passed in child is not connected to another Visual.
/// </summary>
/// <exception cref="ArgumentException">If the new child has already a parent or if the slot a the specified index is not null.</exception>
private void ConnectChild(int index, Visual value)
{
//
// -- Approved By The Core Team --View on GitHub (pinned to 81131a70a4)