dotnet/wpf · error

Only Decorator and ScrollViewer can be used as…

Error message

Only Decorator and ScrollViewer can be used as PART_ContentHost.

What it means

During template application, if PasswordBox's PART_ContentHost template part is neither a ScrollViewer nor a Decorator, WPF nulls it out and throws NotSupportedException. Only those two element types can host the password render scope; anything else (Grid, ContentControl, etc.) is rejected.

Solutions

  1. Change the PART_ContentHost element to a ScrollViewer or Border (Decorator)
  2. Remove the PART_ContentHost name from invalid elements if no content host is needed
  3. Copy the default PasswordBox ControlTemplate as the starting point so the part types are correct
  4. Verify the element declared in the template: ScrollViewer for scrolling text, Border/Decorator for simple hosting

Example fix

// before
<Grid x:Name="PART_ContentHost"/> <!-- throws -->
// after
<ScrollViewer x:Name="PART_ContentHost"/>
Defensive patterns

Strategy: validation

Validate before calling

var host = template.FindName("PART_ContentHost", passwordBox) as FrameworkElement;
bool ok = host is ScrollViewer || host is Decorator; // must be one of these two types

Type guard

bool isValidContentHost(FrameworkElement fe) => fe is ScrollViewer || fe is Decorator;

Prevention

When it happens

Trigger: A custom PasswordBox ControlTemplate that names some element PART_ContentHost where that element is not a ScrollViewer or Decorator (e.g. a Grid, ContentPresenter, or Border-derived non-decorator type mismatch), when the template is applied.

Common situations: Authoring a PasswordBox template from scratch and guessing the content-host type; renaming a Grid to PART_ContentHost; porting templates between controls with different content-host requirements.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/91987dafb452feb7. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/PasswordBox.cs:970

                }
                else
                {
                    decorator.Child = _renderScope; // this may replace old render scope in case of upgrade scenario in TextBox
                }
            }
            else
            {
                // When we implement TextContainer setting via TextView interface
                // all text containing element will become allowed here.
                _renderScope = null;

                // Explicitly not throwing an exception here when content host = null
                // -- designers need us to support no content scenarios
                if (_passwordBoxContentHost != null)
                {
                    _passwordBoxContentHost = null;
                    //  Remove the exception
                    throw new NotSupportedException(SR.PasswordBoxInvalidTextContainer);
                }
            }

            // Attach render scope to TextEditor
            InitializeRenderScope();

            FrameworkElement element = _renderScope;
            while (element != this && element != null)  // checking both just to be safe
            {
                if (element is Border)
                {
                    _border = (Border)element;
                }
                element = element.Parent as FrameworkElement;
            }
        }

        private void ClearContentHost()

View on GitHub (pinned to 81131a70a4)