{"record":{"id":"217a84c35949e687","repo":"dotnet/wpf","slug":"sr-format-sr-itemspanelnotapanel-root-type","errorCode":null,"errorMessage":"SR.Format(SR.ItemsPanelNotAPanel, root.Type)","messagePattern":"SR\\.Format\\(SR\\.ItemsPanelNotAPanel, root\\.Type\\)","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/ItemsPanelTemplate.cs","lineNumber":125,"sourceCode":"            if( HasContent )\n            {\n                // This is a Baml-style template\n\n                // Validate the root type (it must be a Panel)\n\n                TemplateContent templateHolder = Template as TemplateContent;\n                System.Xaml.XamlType panelType = templateHolder.SchemaContext.GetXamlType(typeof(Panel));\n                if (templateHolder.RootType == null || !templateHolder.RootType.CanAssignTo(panelType))\n                {\n                    throw new InvalidOperationException(SR.Format(SR.ItemsPanelNotAPanel, templateHolder.RootType));\n                }\n            }\n\n            else if ((root = this.VisualTree) != null)\n            {\n                // This is a FEF-style template\n                if (!typeof(Panel).IsAssignableFrom(root.Type))\n                    throw new InvalidOperationException(SR.Format(SR.ItemsPanelNotAPanel, root.Type));\n\n                root.SetValue(Panel.IsItemsHostProperty, true);\n            }\n        }\n\n\n        #endregion Internal Methods\n\n        #region Protected Methods\n\n        //-------------------------------------------------------------------\n        //\n        //  Protected Methods\n        //\n        //-------------------------------------------------------------------\n\n        /// <summary>\n        ///     Validate against the following rules","sourceCodeStart":107,"sourceCodeEnd":143,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/ItemsPanelTemplate.cs#L107-L143","documentation":"ItemsPanelTemplate's VisualTree must be a single Panel (the items host). During template sealing, ProcessTemplateBeforeSeal checks typeof(Panel).IsAssignableFrom(root.Type) and throws InvalidOperationException when the template's root element is not a Panel (e.g. a Border or Grid nested incorrectly). WPF requires this because the ItemsPresenter must find a panel to lay out generated item containers.","triggerScenarios":"Defining an <ItemsPanelTemplate> whose root element is not a Panel (e.g. <Border>, <ContentControl>, or <TextBlock>) and applying it via ItemsControl.ItemsPanel or calling LoadContent/ApplyTemplate on such a template.","commonSituations":"Wrapping a StackPanel/VirtualizingStackPanel inside a <Border> inside ItemsPanelTemplate to try to add background or padding; copy-pasting a ControlTemplate into an ItemsPanelTemplate; migration from other frameworks where wrappers are common.","solutions":["Make the root element of the ItemsPanelTemplate a Panel-derived type (StackPanel, WrapPanel, VirtualizingStackPanel, Grid, Canvas, DockPanel).","Move wrapper properties (margin, background) onto the Panel itself instead of a Border wrapper.","If wrapper behavior is truly needed, use a Grid (a Panel) as root and attach decorations via panel properties or restructure the control template instead."],"exampleFix":"<!-- before -->\n<ItemsPanelTemplate>\n  <Border Background=\"LightGray\">\n    <StackPanel/>\n  </Border>\n</ItemsPanelTemplate>\n<!-- after -->\n<ItemsPanelTemplate>\n  <StackPanel Background=\"LightGray\"/>\n</ItemsPanelTemplate>","handlingStrategy":"validation","validationCode":"var tpl = myItemsControl.ItemsPanel;\nvar content = tpl?.LoadContent();\nif (content != null && content is not Panel)\n    throw new InvalidOperationException($\"ItemsPanelTemplate root must be a Panel, got {content.GetType().Name}\");","typeGuard":"static bool IsValidItemsPanel(FrameworkElement root) => root is Panel;","tryCatchPattern":"try { element.ApplyTemplate(); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"panel\")) { /* fix template or fallback to default ItemsPanel */ }","preventionTips":["Never wrap the items panel in Border/Grid-like non-panel containers inside ItemsPanelTemplate.","Root of ItemsPanelTemplate must be a Panel-derived type; put styling properties on the panel itself.","Test custom ItemsPanelTemplate at first template application, not just at runtime data load."],"tags":["wpf","xaml","itemspaneltemplate","invalid-xaml"],"backgroundTag":"incompatible-source-type","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"}