Why would 'this.ContentTemplate.FindName' throw an InvalidOperationException on its own template?

Mark A. Donohoe picture Mark A. Donohoe · Apr 15, 2011 · Viewed 9.2k times · Source

Ok... this has me stumped. I've overridden OnContentTemplateChanged in my UserControl. I'm checking that the value passed in for newContentTemplate does in fact equal this.ContentTemplate (it does) yet when I call this...

var textBox = this.ContentTemplate.FindName("EditTextBox", this);

...it throws the following exception...

"This operation is valid only on elements that have this template applied."

Per a commenter in another related question, he said you're supposed to pass in the content presenter for the control, not the control itself, so I then tried this...

var cp = FindVisualChild<ContentPresenter>(this);

var textBox = this.ContentTemplate.FindName("EditTextBox", cp);

where FindVisualChild is just a helper function used in MSDN's example (see below) to find the associated content presenter. While 'cp' is found, it too throws the same error. I'm stumped!!

Here's the helper function for reference...

private childItem FindVisualChild<childItem>(DependencyObject obj)
    where childItem : DependencyObject
{
    for(int i = 0 ; i < VisualTreeHelper.GetChildrenCount(obj) ; i++)
    {
        DependencyObject child = VisualTreeHelper.GetChild(obj, i);
        if(child != null && child is childItem)
            return (childItem)child;
        else
        {
            childItem childOfChild = FindVisualChild<childItem>(child);
            if(childOfChild != null)
                return childOfChild;
        }
    }
    return null;
}

M

Answer

Mike Fuchs picture Mike Fuchs · Mar 18, 2013

Explicitly applying the template before calling the FindName method will prevent this error.

this.ApplyTemplate();