Ok... this has me stumped. I've overridden OnContentTemplateChanged
in my UserControl
subclass. 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 TChildItem FindVisualChild<TChildItem>(DependencyObject obj)
where TChildItem : DependencyObject {
for(int i = 0 ; i < VisualTreeHelper.GetChildrenCount(obj) ; i++) {
var child = VisualTreeHelper.GetChild(obj, i);
if(child is TChildItem typedChild) {
return typedChild;
}
else {
var childOfChild = FindVisualChild<TChildItem>(child);
if(childOfChild != null)
return childOfChild;
}
}
return null;
}
Explicitly applying the template before calling the FindName
method will prevent this error.
this.ApplyTemplate();