{"record":{"id":"1471d163e2dea770","repo":"dotnet/wpf","slug":"sr-visual-hasparent","errorCode":null,"errorMessage":"SR.Visual_HasParent","messagePattern":"SR\\.Visual_HasParent","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Visual.cs","lineNumber":2579,"sourceCode":"        ///    method to find out where the child was added.\n        ///\n        ///  Remark: To move a Visual child in a collection it must be first disconnected and then connected\n        ///    again. (Moving forward we might want to add a special optimization there so that we do not\n        ///    unmarshal our composition resources).\n        ///\n        ///    It is okay to type this protected API to the 2D Visual.  The only 2D Visual with\n        ///    3D childern is the Viewport3DVisual which is sealed.\n        /// </summary>\n        protected void AddVisualChild(Visual child)\n        {\n            if (child == null)\n            {\n                return;\n            }\n\n            if (child._parent != null)\n            {\n                throw new ArgumentException(SR.Visual_HasParent);\n            }\n\n            // invalid during a VisualTreeChanged event\n            VisualDiagnostics.VerifyVisualTreeChange(this);\n\n            SetFlags(true, VisualFlags.HasChildren);\n\n            // Set the parent pointer.\n\n            child._parent = this;\n\n            //\n            // The child might be dirty. Hence we need to propagate dirty information\n            // from the parent and from the child.\n            //\n\n            Visual.PropagateFlags(\n                this,","sourceCodeStart":2561,"sourceCodeEnd":2597,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Visual.cs#L2561-L2597","documentation":"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.","triggerScenarios":"Calling AddVisualChild (or re-parenting APIs) with a Visual that is currently attached to another parent without removing it first.","commonSituations":"Reusing visual instances across containers; forgetting RemoveVisualChild before re-adding; moving a child from one panel to another while it is still connected.","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"],"exampleFix":"// before\nnewParent.AddVisualChild(sharedChild);\n// after\noldParent.RemoveVisualChild(sharedChild);\nnewParent.AddVisualChild(sharedChild);","handlingStrategy":"validation","validationCode":"if (VisualTreeHelper.GetParent(child) != null) oldParent.RemoveVisualChild(child);","typeGuard":"bool IsUnparented(Visual c) => VisualTreeHelper.GetParent(c) == null;","tryCatchPattern":"try { parent.AddVisualChild(child); } catch (ArgumentException) { /* child already parented: detach and retry */ }","preventionTips":["Always detach a visual from its current parent before re-parenting","Avoid sharing visual instances across containers","Track ownership of custom visual children"],"tags":["wpf","visual-tree","already-parented"],"backgroundTag":"invalid-state-transition","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-21T21:30:21.729Z"}