dotnet/wpf · error · InvalidOperationException

SR.TemplateFindNameInInvalidElement

Error message

SR.TemplateFindNameInInvalidElement

What it means

Template.FindName throws InvalidOperationException (SR.TemplateFindNameInInvalidElement) when the templatedParent argument is not an element instantiated BY this specific template (i.e. templatedParent.TemplateInternal != this). Names inside a template's namescope are only resolvable through the template that created that scope.

Solutions

  1. Pass the control that is actually templated by this template instance: use control.Template (or FrameworkElement.FindName directly on it).
  2. Prefer element.FindName(name) or NameScope.GetNameScope on the templated child instead of raw template.FindName.
  3. Ensure the template reference used for FindName is the same instance as control.Template, not a resource lookup that yields a different copy.

Example fix

// before
var tpl = (ControlTemplate)Application.Current.Resources["tpl"];
var tb = (TextBlock)tpl.FindName("text", myButton); // throws: myButton.TemplateInternal != tpl
// after
var tb = (TextBlock)myButton.Template.FindName("text", myButton);
Defensive patterns

Strategy: validation

Validate before calling

if (ReferenceEquals(templatedParent?.TemplateInternal, template))
    var found = template.FindName(name, templatedParent);

Type guard

static bool OwnsTemplate(FrameworkTemplate t, FrameworkElement e) => ReferenceEquals(e?.TemplateInternal, t);

Try / catch

try { return template.FindName(name, element); }
catch (InvalidOperationException) { return element?.FindName(name); }

Prevention

When it happens

Trigger: Calling template.FindName(name, element) where element's TemplateInternal is a different template instance — e.g. the element uses another template, the template was re-applied (so the instance is stale), or the caller passes the wrong element (a plain content child rather than a templated child).

Common situations: Passing a Window/UserControl instead of the templated control; retrieving a template from Application resources but searching within a control that uses a copied/retemplated instance; control template re-applied after theme change leaving a stale template reference.

Understand the failure class

Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.

Related errors


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

Appendix: source

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

        /// <summary>
        /// FindName - Finds the element associated with the id defined under this control template.
        ///          Context of the FrameworkElement where this template is applied will be passed
        ///          as parameter.
        /// </summary>
        /// <param name="name">string name</param>
        /// <param name="templatedParent">context where this template is applied</param>
        /// <returns>the element associated with the Name</returns>
        public Object FindName(string name, FrameworkElement templatedParent)
        {
            // Verify Context Access
            VerifyAccess();

            ArgumentNullException.ThrowIfNull(templatedParent);

            if (this != templatedParent.TemplateInternal)
            {
                throw new InvalidOperationException(SR.TemplateFindNameInInvalidElement);
            }

            return StyleHelper.FindNameInTemplateContent(templatedParent, name, this);
        }

        #endregion PublicProperties


        #region INameScope

        /// <summary>
        /// Registers the name - Context combination
        /// </summary>
        /// <param name="name">Name to register</param>
        /// <param name="scopedElement">Element where name is defined</param>
        public void RegisterName(string name, object scopedElement)
        {
            // Verify Context Access

View on GitHub (pinned to 81131a70a4)