{"record":{"id":"6df7cb7dd9529aa9","repo":"dotnet/wpf","slug":"sr-haslogicalparent-frameworkelementtemplate","errorCode":null,"errorMessage":"SR.HasLogicalParent","messagePattern":"SR\\.HasLogicalParent","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/WpfGfx/codegen/mcg/generators/FrameworkElementTemplate.cs","lineNumber":364,"sourceCode":"                                        ///////////////////\n\n                                        //\n                                        // -- Approved By The Core Team --\n                                        //\n                                        // Do not allow foreign threads to change the tree.\n                                        // (This is a noop if this object is not assigned to a Dispatcher.)\n                                        //\n                                        // We also need to ensure that the tree is homogenous with respect\n                                        // to the dispatchers that the elements belong to.\n                                        //\n                                        this.VerifyAccess();\n                                        newParent?.VerifyAccess();\n\n                                        // Logical Parent must first be dropped before you are attached to a newParent\n                                        // This mitigates illegal tree state caused by logical child stealing as illustrated in bug 970706\n                                        if (_parent != null && newParent != null && _parent != newParent)\n                                        {\n                                            throw new System.InvalidOperationException(SR.HasLogicalParent);\n                                        }\n\n                                        // Trivial check to avoid loops\n                                        if (newParent == this)\n                                        {\n                                            throw new System.InvalidOperationException(SR.CannotBeSelfParent);\n                                        }\n\n                                        // invalid during a VisualTreeChanged event\n                                        VisualDiagnostics.VerifyVisualTreeChange(this);\n\n                                        // Logical Parent implies no InheritanceContext\n                                        if (newParent != null)\n                                        {\n                                            ClearInheritanceContext();\n                                        }\n\n                                        IsParentAnFE = newParent is FrameworkElement;","sourceCodeStart":346,"sourceCodeEnd":382,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/WpfGfx/codegen/mcg/generators/FrameworkElementTemplate.cs#L346-L382","documentation":"A logical element can have only one logical parent. In the ChangeLogicalParent path, if the element already has a parent (_parent) and a different newParent is supplied, it throws InvalidOperationException(SR.HasLogicalParent) to prevent 'logical child stealing' (see bug 970706) and corrupt trees.","triggerScenarios":"Calling ChangeLogicalParent(newParent) — or APIs that set Parent — on an element that already belongs to a different logical parent, without detaching first.","commonSituations":"Moving a UIElement from one container to another without removing it first; adding the same shared resource/child instance to two panels; re-parenting content items in a custom control.","solutions":["Remove the child from its current logical parent before attaching to the new one","Clear the old parent: oldParent.RemoveLogicalChild(child) then newParent.AddLogicalChild(child)","Create a new instance for the second parent instead of sharing one element"],"exampleFix":"// before\npanelB.Children.Add(sharedChild); // sharedChild.Parent == panelA\n// after\npanelA.Children.Remove(sharedChild);\npanelB.Children.Add(sharedChild);","handlingStrategy":"validation","validationCode":"if (child.Parent != null && !ReferenceEquals(child.Parent, newParent)) throw new InvalidOperationException(\"Child already has a different logical parent; detach first.\");","typeGuard":"bool IsReparentSafe(System.Windows.DependencyObject child, object newParent) => child.Parent == null || ReferenceEquals(child.Parent, newParent);","tryCatchPattern":"try { newParent.AddLogicalChild(child); } catch (InvalidOperationException ex) when (ex.Message.Contains(\"logical parent\")) { ((FrameworkElement)child.Parent)?.RemoveLogicalChild(child); newParent.AddLogicalChild(child); }","preventionTips":["Always remove a child from its current parent before re-adding","Never share a single UIElement instance between two containers","Wrap reparenting in a MoveChild helper that detaches first"],"tags":["wpf","logical-tree","parenting","invalid-operation"],"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-22T01:17:13.364Z"}