dotnet/wpf · error · NotSupportedException
SR.TextBoxScrollViewerMarkedAsTextBoxContentMustHaveNoConten…
Error message
SR.TextBoxScrollViewerMarkedAsTextBoxContentMustHaveNoContent
What it means
When TextBoxBase finds a ScrollViewer marked as its text-box content part (via template parts) whose Content is already set, it aborts attaching the internal render scope and throws NotSupportedException. A ScrollViewer designated as PART content host must have no other content, since TextBoxBase installs its own editing scope into it.
Solutions
- Remove all content from the ScrollViewer part in the template; host extra visuals in a sibling Grid overlay instead.
- Name the ScrollViewer part correctly (PART_ContentHost) and leave its Content empty so TextBoxBase can attach its render scope.
- Base custom templates on the default TextBox template and only modify styling, not the part structure.
Example fix
// before
<ScrollViewer x:Name="PART_ContentHost">
<TextBlock Text="extra"/> <!-- content present -> throws -->
</ScrollViewer>
// after
<Grid>
<ScrollViewer x:Name="PART_ContentHost"/>
<TextBlock Text="extra" IsHitTestVisible="False"/>
</Grid> Defensive patterns
Strategy: validation
Validate before calling
// In the template, before apply:
bool contentHostIsEmpty = scrollViewerPart.Content == null;
if (!contentHostEmpty) throw new InvalidOperationException("PART_ContentHost ScrollViewer must have no content"); Type guard
static bool IsValidTextBoxContentHost(ScrollViewer sv) => sv != null && sv.Content == null;
Try / catch
try
{
textBox.Template = customTemplate;
textBox.ApplyTemplate();
}
catch (NotSupportedException)
{
textBox.Template = null; // revert to default template
} Prevention
- Never place children directly inside the PART_ContentHost ScrollViewer
- Use sibling overlay elements for watermarks/badges
- Base custom templates on the extracted default template
When it happens
Trigger: Applying a custom ControlTemplate for TextBox/TextBoxBase where the ScrollViewer part already contains child elements (x:Bind content, injected children, or leftover content from a modified template).
Common situations: Hand-edited or third-party TextBox templates that place extra visuals directly inside the content-host ScrollViewer instead of in an adorner/overlay layer; template upgrades between framework versions.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- SR.TextBoxDecoratorMarkedAsTextBoxContentMustHaveNoContent
- SR.TextBoxInvalidTextContainer
- SR.FlowDocumentReaderDecoratorMarkedAsContentHostMustHaveNoC…
- SR.DocumentViewerStyleMustIncludeContentHost
- By default, ToolTip property does not support ToolTip…
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/b2e9304985fae97c.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/Primitives/TextBoxBase.cs:1901
ClearContentHost();
// Find ContentHostTemplateName in the style
_textBoxContentHost = GetTemplateChild(ContentHostTemplateName) as FrameworkElement;
// Note that we allow ContentHostTemplateName to be optional.
// This simplifies toolability of our control styling.
// When the ContentHostTemplateName is not found or incorrect
// TextBox goes into disabled state, but not throw.
// Add renderScope as a child of ContentHostTemplateName
_renderScope = renderScope;
if (_textBoxContentHost is ScrollViewer scrollViewer)
{
if (scrollViewer.Content != null)
{
_renderScope = null;
_textBoxContentHost = null;
// Do not throw exception
throw new NotSupportedException(SR.TextBoxScrollViewerMarkedAsTextBoxContentMustHaveNoContent);
}
else
{
scrollViewer.Content = _renderScope; // this may replace old render scope in case of upgrade scenario in TextBox
}
}
else if (_textBoxContentHost is Decorator decorator)
{
if (decorator.Child != null)
{
_renderScope = null;
_textBoxContentHost = null;
// Do not throw exception
throw new NotSupportedException(SR.TextBoxDecoratorMarkedAsTextBoxContentMustHaveNoContent);
}
else
{
decorator.Child = _renderScope; // this may replace old render scope in case of upgrade scenario in TextBoxView on GitHub (pinned to 81131a70a4)