dotnet/wpf · error · XamlParseException

SR.TemplateContentSetTwice

Error message

SR.TemplateContentSetTwice

What it means

FrameworkTemplate.Content (or the Xaml-set template content) throws XamlParseException (SR.TemplateContentSetTwice) when template content is assigned more than once. A template may hold either a XAML node stream or a VisualTree/Factory definition, and assigning content after it was already set would silently discard the first definition.

Solutions

  1. Create a new ControlTemplate/FrameworkTemplate instance for each distinct content assignment.
  2. Set template content exactly once, at construction/XAML load time.
  3. If content must vary, swap whole templates on the control (control.Template = newTemplate) instead of mutating one template.

Example fix

// before
ControlTemplate ct = (ControlTemplate)FindResource("tpl");
ct.Content = buttonFactory; // throws if XAML content already set
// after
ControlTemplate ct = new ControlTemplate(typeof(Button));
ct.Content = buttonFactory;
Defensive patterns

Strategy: validation

Validate before calling

if (templateHasContentAlready) // track your own assignment flag
    template = new ControlTemplate(targetType);
template.Content = newContent;

Try / catch

try { template.Content = value; }
catch (XamlParseException) { template = new ControlTemplate(targetType) { Content = value }; }

Prevention

When it happens

Trigger: Assigning FrameworkTemplate.Content twice; loading XAML that defines template content and then programmatically setting Content on the same template instance; reusing a deserialized ControlTemplate/FrameworkTemplate object with new content.

Common situations: Reusing a single ControlTemplate instance for multiple controls while also re-setting its content; template hot-reload code that reassigns Content; building templates in code after parsing one from XAML.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/FrameworkTemplate.cs:199

        {
            get
            {
                return _templateHolder;
            }
            set
            {
                CheckSealed();

                if (!_hasXamlNodeContent)
                {
                    value.OwnerTemplate = this;
                    value.ParseXaml();
                    _templateHolder = value;
                    _hasXamlNodeContent = true;
                }
                else
                {
                    throw new System.Windows.Markup.XamlParseException(SR.TemplateContentSetTwice);
                }
            }
        }

        /// <summary>
        ///     The collection of resources that can be
        ///     consumed by the container and its sub-tree.
        /// </summary>
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        [Ambient]
        public ResourceDictionary Resources
        {
            get
            {
                // Verify Context Access
                VerifyAccess();

                if ( _resources == null )

View on GitHub (pinned to 81131a70a4)