{"record":{"id":"380da9be27fa4b13","repo":"dotnet/wpf","slug":"sr-compositiontarget-rootvisual-hasparent","errorCode":null,"errorMessage":"SR.CompositionTarget_RootVisual_HasParent","messagePattern":"SR\\.CompositionTarget_RootVisual_HasParent","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/CompositionTarget.cs","lineNumber":461,"sourceCode":"\n        /// <summary>\n        /// Internal method to set the root visual.\n        /// </summary>\n        /// <param name=\"visual\">Root visual, can be null, but can not be a child of another\n        /// Visual.</param>\n        private void SetRootVisual(Visual visual)\n        {\n            // We need to make this function robust by leaving the\n            // _rootVisual in a consistent state.\n\n            if (visual != null &&\n                (visual._parent != null\n                 || visual.IsRootElement))\n            {\n                // If a Visual has already a parent it can not be the root in a CompositionTarget because\n                // otherwise we would have two CompositionTargets party on the same Visual tree.\n                // If want to allow this we need to explicitly add support for this.\n                throw new System.ArgumentException(SR.CompositionTarget_RootVisual_HasParent);\n            }\n\n            DUCE.ChannelSet channelSet = MediaContext.From(Dispatcher).GetChannels();\n            DUCE.Channel channel = channelSet.Channel;\n            if (_rootVisual != null && _contentRoot.IsOnChannel(channel))\n            {\n                ClearRootNode(channel);\n\n                ((DUCE.IResource)_rootVisual).ReleaseOnChannel(channel);\n\n                _rootVisual.IsRootElement = false;\n            }\n\n            _rootVisual = visual;\n\n            if (_rootVisual != null)\n            {\n                _rootVisual.IsRootElement = true;","sourceCodeStart":443,"sourceCodeEnd":479,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/CompositionTarget.cs#L443-L479","documentation":"CompositionTarget.SetRootVisual throws ArgumentException because the visual passed to RootVisual already has a parent (or is already marked as a root element). WPF cannot allow two CompositionTargets to render the same visual tree, so the visual must be parentless when it becomes a composition root.","triggerScenarios":"Setting CompositionTarget.RootVisual (in MediaContext/RenderMessageHandler context) with a Visual whose Visual._parent != null or whose IsRootElement is already true — e.g. reusing a visual already attached to another HwndSource, another CompositionTarget, or an element already added to a visual tree.","commonSituations":"Re-hosting a control that is already in a Window's tree into a second HwndSource/CompositionTarget; calling RootVisual twice with overlapping trees; moving a visual between two render targets without detaching it first.","solutions":["Detach the visual from its current parent (remove it from its parent's Children/Child collection) before assigning it as RootVisual.","Create a new visual instance for each CompositionTarget instead of sharing one visual tree.","Check visual.Parent (or VisualTreeHelper.GetParent) is null before setting RootVisual."],"exampleFix":"// before\ncompositionTarget.RootVisual = existingCanvas; // canvas already has a parent\n// after\n((Panel)existingCanvas.Parent).Children.Remove(existingCanvas);\ncompositionTarget.RootVisual = existingCanvas;","handlingStrategy":"validation","validationCode":"if (visual != null && (VisualTreeHelper.GetParent(visual) != null)) throw new InvalidOperationException(\"Visual already has a parent; detach it before setting RootVisual.\");\ncompositionTarget.RootVisual = visual;","typeGuard":"static bool CanBeRootVisual(Visual v) => v != null && VisualTreeHelper.GetParent(v) == null;","tryCatchPattern":null,"preventionTips":["One visual tree per CompositionTarget — never share a tree between render targets.","Detach a visual from its parent before re-hosting it.","Set RootVisual only once per target lifecycle; reset to null before swapping."],"tags":["wpf","composition","visual-tree"],"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"}