{"record":{"id":"817dcf5d3e95e1c8","repo":"dotnet/wpf","slug":"sr-reparentmodelchildillegal","errorCode":null,"errorMessage":"SR.ReparentModelChildIllegal","messagePattern":"SR\\.ReparentModelChildIllegal","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/Controls/InnerItemCollectionView.cs","lineNumber":714,"sourceCode":"        }\n\n        // check that item is not already parented\n        // throws an exception if already parented\n        private DependencyObject AssertPristineModelChild(object item)\n        {\n            DependencyObject node = item as DependencyObject;\n            if (node == null)\n            {\n                return null;\n            }\n\n            // refuse a child which already has a different model parent!\n            // NOTE: model tree spec would allow reparenting if the parent does not change\n            //  but this code will throw: this is a efficient way to catch\n            //  an attempt to add the same element twice to the collection\n            if (LogicalTreeHelper.GetParent(node) != null)\n            {\n                throw new InvalidOperationException(SR.ReparentModelChildIllegal);\n            }\n            return node;\n        }\n\n        // NOTE: Only change the item's logical links if the host is a Visual (bug 986386)\n        private void SetModelParent(object item)\n        {\n            // to avoid the unnecessary, expensive code in AddLogicalChild, check for DO first\n            if ((ModelParentFE != null) && (item is DependencyObject))\n                LogicalTreeHelper.AddLogicalChild(ModelParentFE, null, item);\n        }\n\n        // if item implements IModelTree, clear model parent\n        private void ClearModelParent(object item)\n        {\n            // ClearModelParent is also called for items that are not a DependencyObject;\n            // to avoid the unnecessary, expensive code in RemoveLogicalChild, check for DO first\n            if ((ModelParentFE != null) && (item is DependencyObject))","sourceCodeStart":696,"sourceCodeEnd":732,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/Controls/InnerItemCollectionView.cs#L696-L732","documentation":"InnerItemCollectionView refuses to add a model child (ItemsControl item that participates in the logical tree) which already has a logical parent. WPF throws InvalidOperationException('ReparentModelChildIllegal') because re-parenting an element into a second collection would corrupt the logical tree; the throw also doubles as a fast guard against adding the same element twice to the same collection.","triggerScenarios":"Calling ItemsControl.Items.Add (or Remove followed by re-Add before the tree has detached the child) with a DependencyObject that still has LogicalTreeHelper.GetParent(node) != null, e.g. adding an element to two ItemsControls at once, or re-adding an item to the same collection without removing it first.","commonSituations":"Reusing UIElement instances across ItemsControls (e.g. moving a node between two TreeViews), adding an item that was declared as XAML content of another container, binding a collection containing elements already parented in the visual/logical tree, or a collection-change race where Remove has not yet detached the node.","solutions":["Remove the item from its current logical parent before adding it (e.g. (prevParent as ItemsControl)?.Items.Remove(item), or detach from a Panel).","Do not share a single element instance between two collections; create a new instance per collection.","If the item should be moved, use a MVVM data-item collection (ItemsSource) instead of directly parenting UIElements so the container is generated per collection.","Check for duplicate Add calls: verify the item is not already in the collection before adding."],"exampleFix":"// before\ntreeView2.Items.Add(node); // node still has logical parent treeView1\n// after\ntreeView1.Items.Remove(node);\ntreeView2.Items.Add(node);","handlingStrategy":"validation","validationCode":"bool canAdd = item is DependencyObject d && LogicalTreeHelper.GetParent(d) == null;","typeGuard":"static bool HasLogicalParent(object item) =>\n    item is DependencyObject d && LogicalTreeHelper.GetParent(d) != null;","tryCatchPattern":"try { items.Add(node); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"parent\")) { items.Remove(node); items.Add(node); }","preventionTips":["Never share UIElement instances across two ItemsControls; use data items + ItemsSource.","Always Remove an element from its current parent before adding it elsewhere.","Prefer MVVM data collections over directly parenting UIElements.","Check LogicalTreeHelper.GetParent in debug asserts before Add calls."],"tags":["wpf","logical-tree","collection"],"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"}