{"record":{"id":"e9b26824f76bdf23","repo":"dotnet/wpf","slug":"visualtree-of-itemspaneltemplate-must-be-a-single-element","errorCode":null,"errorMessage":"VisualTree of ItemsPanelTemplate must be a single element.","messagePattern":"VisualTree of ItemsPanelTemplate must be a single element\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/ItemsPresenter.cs","lineNumber":46,"sourceCode":"        /// <summary>\n        /// Called when the Template's tree is about to be generated\n        /// </summary>\n        internal override void OnPreApplyTemplate()\n        {\n            base.OnPreApplyTemplate();\n            AttachToOwner();\n        }\n\n        /// <summary>\n        ///     This is the virtual that sub-classes must override if they wish to get\n        ///     notified that the template tree has been created.\n        /// </summary>\n        public override void OnApplyTemplate()\n        {\n            // verify that the template produced a panel with no children\n            Panel panel = GetVisualChild(0) as Panel;\n            if (panel == null || VisualTreeHelper.GetChildrenCount(panel) > 0)\n                throw new InvalidOperationException(SR.ItemsPanelNotSingleNode);\n\n            OnPanelChanged(this, EventArgs.Empty);\n\n            base.OnApplyTemplate();\n        }\n\n        //------------------------------------------------------\n        //\n        // Protected Methods\n        //\n        //------------------------------------------------------\n\n        /// <summary>\n        /// Override of <seealso cref=\"FrameworkElement.MeasureOverride\" />.\n        /// </summary>\n        /// <param name=\"constraint\">Constraint size is an \"upper limit\" that the return value should not exceed.</param>\n        /// <returns>The ItemsPresenter's desired size.</returns>\n        protected override Size MeasureOverride(Size constraint)","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/ItemsPresenter.cs#L28-L64","documentation":"After the template is applied, ItemsPresenter.OnApplyTemplate verifies the generated visual tree contains a single child that is a Panel with no children of its own. If the first visual child is not a Panel or the panel already has children, it throws InvalidOperationException because the presenter will reparent generated item containers into this panel and cannot tolerate existing content.","triggerScenarios":"A ControlTemplate places content inside the panel used as items host (e.g. <StackPanel><TextBlock/>...</StackPanel> inside an ItemsPresenter); the template's first visual child is not a Panel (e.g. a Border wrapping the panel) when OnApplyTemplate runs; manually calling ApplyTemplate on such a template.","commonSituations":"Custom control templates that add headers or footers directly inside the items panel; nesting the panel inside a Border so the first visual child is not a Panel; overriding OnApplyTemplate in derived controls that add children before base.OnApplyTemplate.","solutions":["Ensure the items panel has no hardcoded children; put headers/footers outside the panel in the control template.","Make the panel the direct (first) visual child the presenter sees; wrap the panel in a Border outside, not inside, the presenter's scope.","Use Panel properties (Background, Padding via wrapping layout) instead of child elements to style the items area."],"exampleFix":"<!-- before -->\n<ControlTemplate TargetType=\"ListBox\">\n  <StackPanel>\n    <TextBlock Text=\"Header\"/>\n    <ItemsPresenter/>\n  </StackPanel>\n</ControlTemplate>\n<!-- wrong: children inside items panel -->\n<!-- after -->\n<ControlTemplate TargetType=\"ListBox\">\n  <DockPanel>\n    <TextBlock DockPanel.Dock=\"Top\" Text=\"Header\"/>\n    <ItemsPresenter/>\n  </DockPanel>\n</ControlTemplate>","handlingStrategy":"validation","validationCode":"var presenter = GetTemplateChild(\"ItemsPresenter\") as ItemsPresenter;\n// after ApplyTemplate:\nvar firstChild = VisualTreeHelper.GetChild(presenter, 0) as Panel;\nif (firstChild == null || VisualTreeHelper.GetChildrenCount(firstChild) > 0)\n    throw new InvalidOperationException(\"ItemsPresenter template must yield a childless Panel as its first visual child\");","typeGuard":"static bool IsSingleChildlessPanel(ItemsPresenter p) => VisualTreeHelper.GetChildrenCount(p) > 0 && VisualTreeHelper.GetChild(p, 0) is Panel panel && VisualTreeHelper.GetChildrenCount(panel) == 0;","tryCatchPattern":"try { presenter.ApplyTemplate(); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"single element\")) { /* regenerate template without panel children */ }","preventionTips":["Keep the items panel empty; render headers/footers outside the panel in the control template.","Do not nest the panel inside another visual inside the ItemsPresenter subtree.","Review custom ControlTemplates for accidental children inside the items-host panel."],"tags":["wpf","templates","itemspresenter","visual-tree"],"backgroundTag":"internal-invariant-violation","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"}