dotnet/wpf · error · ArgumentException
SR.Visual_HasParent
Error message
SR.Visual_HasParent
What it means
Visual.AddVisualChild throws ArgumentException(SR.Visual_HasParent) when the child visual passed already has a parent. A Visual may only have one parent in the visual tree, so attaching an already-parented child is rejected.
Solutions
- Call RemoveVisualChild / remove from the old parent before adding to the new parent
- Create a new Visual instance instead of reusing one already in a tree
- Check Visual.Parent (or child._parent via VisualTreeHelper.GetParent) is null before adding
Example fix
// before newParent.AddVisualChild(sharedChild); // after oldParent.RemoveVisualChild(sharedChild); newParent.AddVisualChild(sharedChild);
Defensive patterns
Strategy: validation
Validate before calling
if (VisualTreeHelper.GetParent(child) != null) oldParent.RemoveVisualChild(child);
Type guard
bool IsUnparented(Visual c) => VisualTreeHelper.GetParent(c) == null;
Try / catch
try { parent.AddVisualChild(child); } catch (ArgumentException) { /* child already parented: detach and retry */ } Prevention
- Always detach a visual from its current parent before re-parenting
- Avoid sharing visual instances across containers
- Track ownership of custom visual children
When it happens
Trigger: Calling AddVisualChild (or re-parenting APIs) with a Visual that is currently attached to another parent without removing it first.
Common situations: Reusing visual instances across containers; forgetting RemoveVisualChild before re-adding; moving a child from one panel to another while it is still connected.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- ' ' is not a Visual or Visual3D.
- inverse ? SR.Visual_NotADescendant : SR.Visual_NotAnAncestor
- Page can have only Window or Frame as parent.
- Specified index is out of range or child at index is null…
- Specified index is out of range or child at index is null…
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/1471d163e2dea770.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Visual.cs:2579
/// method to find out where the child was added.
///
/// Remark: To move a Visual child in a collection it must be first disconnected and then connected
/// again. (Moving forward we might want to add a special optimization there so that we do not
/// unmarshal our composition resources).
///
/// It is okay to type this protected API to the 2D Visual. The only 2D Visual with
/// 3D childern is the Viewport3DVisual which is sealed.
/// </summary>
protected void AddVisualChild(Visual child)
{
if (child == null)
{
return;
}
if (child._parent != null)
{
throw new ArgumentException(SR.Visual_HasParent);
}
// invalid during a VisualTreeChanged event
VisualDiagnostics.VerifyVisualTreeChange(this);
SetFlags(true, VisualFlags.HasChildren);
// Set the parent pointer.
child._parent = this;
//
// The child might be dirty. Hence we need to propagate dirty information
// from the parent and from the child.
//
Visual.PropagateFlags(
this,View on GitHub (pinned to 81131a70a4)