{"record":{"id":"34a253fb0be36894","repo":"dotnet/maui","slug":"cannot-call-createcontent-directly-on-a-datatempla","errorCode":null,"errorMessage":"Cannot call CreateContent directly on a DataTemplateSelector","messagePattern":"Cannot call CreateContent directly on a DataTemplateSelector","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Controls/src/Core/ElementTemplate.cs","lineNumber":85,"sourceCode":"\t\t{\n\t\t\tif (_changeHandlers == null)\n\t\t\t\treturn;\n\t\t\t_changeHandlers.Remove(onchanged);\n\t\t}\n\n\t\t/// <summary>Used by the XAML infrastructure to load data templates and set up the content of the resulting UI.</summary>\n\t\tpublic object CreateContent()\n\t\t{\n\t\t\tif (LoadTemplate == null)\n\t\t\t{\n\t\t\t\t// Returning a Label here instead of throwing an exception because HotReload may temporarily be in state\n\t\t\t\t// where the user is creating a template; this keeps everything else (which expects a result from CreateContent)\n\t\t\t\t// from crashing during that time. \n\t\t\t\treturn new Label();\n\t\t\t}\n\n\t\t\tif (this is DataTemplateSelector)\n\t\t\t\tthrow new InvalidOperationException(\"Cannot call CreateContent directly on a DataTemplateSelector\");\n\n\t\t\tobject item = LoadTemplate();\n\t\t\tSetupContent(item);\n\n\t\t\tif (item is Element elem)\n\t\t\t\telem.IsTemplateRoot = true;\n\n\t\t\treturn item;\n\t\t}\n\n\t\tinternal virtual void SetupContent(object item)\n\t\t{\n\t\t}\n\n\t\tvoid OnResourcesChanged(object sender, ResourcesChangedEventArgs e)\n\t\t{\n\t\t\tif (_changeHandlers == null)\n\t\t\t\treturn;","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/dotnet/maui/blob/f377ff1c5ee04d334d8a925f50c83a6b7afddf03/src/Controls/src/Core/ElementTemplate.cs#L67-L103","documentation":"Thrown when CreateContent() is called directly on a DataTemplateSelector instance. A DataTemplateSelector is abstract and must first pick a concrete DataTemplate via SelectTemplate(item, container) based on the bound item; it has no single template to instantiate. The guards in ElementTemplate.cs:84 block the parameterless path because it would be ambiguous which child template to materialize.","triggerScenarios":"Calling the parameterless `selector.CreateContent()` on an instance whose runtime type derives from DataTemplateSelector. This happens when generic code holds a `DataTemplate` reference but the object is actually a selector, and it invokes the zero-arg CreateContent rather than the SelectTemplate path.","commonSituations":"Custom layout adapters, cell factories, or test code that receives a DataTemplate and unconditionally calls CreateContent() without first narrowing. Migrating a fixed ItemTemplate to an ItemTemplateSelector without updating the consumption site. Tooling that introspects templates generically.","solutions":["Use the DataTemplateExtensions.CreateContent(this DataTemplate, item, container) overload (DataTemplateExtensions.cs:29), which internally calls SelectDataTemplate then CreateContent.","If you hold the selector explicitly, call selector.SelectTemplate(item, container).CreateContent() instead.","For controls like CollectionView/ListView, assign the selector to the *Selector property (e.g. ItemTemplateSelector) rather than ItemTemplate, so the control drives selection.","Guard with `if (template is DataTemplateSelector s) { ... s.SelectTemplate(...) ... } else { template.CreateContent(); }` when you must branch."],"exampleFix":"// before\nDataTemplate template = GetTemplate();\nvar view = (View)template.CreateContent(); // throws if template is a selector\n\n// after\nusing Microsoft.Maui.Controls.Internals;\nvar view = (View)template.CreateContent(item, container); // routes through SelectTemplate","handlingStrategy":"type-guard","validationCode":"if (template is DataTemplateSelector selector) { return selector.SelectTemplate(item, container); } return template.CreateContent();","typeGuard":"static bool IsSelector(DataTemplate t) => t is DataTemplateSelector;","tryCatchPattern":"try { return template.CreateContent(item, container); } catch (InvalidOperationException) when (template is DataTemplateSelector) { /* use SelectTemplate path */ }","preventionTips":["Always use the DataTemplateExtensions.CreateContent(template, item, container) overload for polymorphic templates.","Assign selectors to *Selector properties (ItemTemplateSelector) rather than the plain ItemTemplate property.","Never call the parameterless CreateContent on a value typed as DataTemplate unless you have ruled out DataTemplateSelector."],"tags":["maui","datatemplate","xaml","controls"],"backgroundTag":null,"analyzedSha":"f377ff1c5ee04d334d8a925f50c83a6b7afddf03","analyzedAt":"2026-08-13T14:26:18.069Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}