dotnet/wpf · error · NotSupportedException

SR.DocumentViewerStyleMustIncludeContentHost

Error message

SR.DocumentViewerStyleMustIncludeContentHost

What it means

During template application DocumentViewer locates the part named in its template that implements the content host (an IDocumentScrollInfo host, a ScrollViewer-based Decorator). If the applied template lacks this ContentHost part, BuildWindowCore/template wiring throws NotSupportedException with SR.DocumentViewerStyleMustIncludeContentHost, because the viewer has nowhere to display documents.

Solutions

  1. Include the required ContentHost element (a Decorator named per DocumentViewer's template contract) in the custom ControlTemplate
  2. Start from the default DocumentViewer template and modify it instead of building one from scratch
  3. Keep the x:Name/ContentHost naming intact when editing the template

Example fix

// before
<ControlTemplate TargetType="DocumentViewer">
  <Border/>
</ControlTemplate>
// after
<ControlTemplate TargetType="DocumentViewer">
  <Decorator Name="PART_ContentHost"/>
</ControlTemplate>
Defensive patterns

Strategy: validation

Validate before calling

// verify template defines the part: template.FindName or ensure x:Name="PART_ContentHost" Decorator exists in the ControlTemplate

Try / catch

try { viewer.ApplyTemplate(); }
catch (NotSupportedException) { /* template missing ContentHost part */ }

Prevention

When it happens

Trigger: Applying a custom ControlTemplate/Style to DocumentViewer that omits the required ContentHost-named part; renaming or removing the ContentHost Decorator in a copied default template.

Common situations: Hand-rolled restyling of DocumentViewer from scratch; theme/template overrides where the default template was copied incompletely.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/DocumentViewer.cs:2059

        /// FindContentHost does 2 things:
        ///  - It finds "marked" elements (elements with ContentHost attached properties)
        ///    in the current Visual Tree.
        ///  - It takes these elements and populates them with the proper UI (for Content)
        /// </summary>
        /// <exception cref="NotSupportedException">There must be a ScrollViewer in
        /// DocumentViewer's visual tree which has the Name PART_ContentHost.</exception>
        private void FindContentHost()
        {
            // Find the "special" element in the tree marked as the
            //   ContentHost.  This element must exist or we throw.
            ScrollViewer contentHost = this.Template.FindName(_contentHostName, this) as ScrollViewer;

            // Make sure contentHost exists.  This wouldn't be much of a DocumentViewer if it didn't,
            //   since we need someplace to throw our IDocumentScrollInfo so we can display documents.
            // Throw an exception if it doesn't exist.
            if (contentHost == null)
            {
                throw new NotSupportedException(SR.DocumentViewerStyleMustIncludeContentHost);
            }

            _scrollViewer = contentHost;
            _scrollViewer.Focusable = false;

            Invariant.Assert(_documentScrollInfo != null, "IDocumentScrollInfo cannot be null.");
            //Make the IDSI the child of the ScrollViewer.
            _scrollViewer.Content = _documentScrollInfo;
            _scrollViewer.ScrollInfo = _documentScrollInfo;

            // Set IDocumentScrollInfo's content if its content is invalid.
            if (_documentScrollInfo.Content != Document)
            {
                AttachContent();
            }
        }

        #region Find

View on GitHub (pinned to 81131a70a4)