Preface
The VisualTreeHelper
“provides utility methods that can be used to traverse object relationships (along child-object or parent-object axes) in the visual tree of your app.”
In this post I will show two extensions to VisualTreeHelper
. Since you cannot create an instance of VisualTreeHelper
, these are not extension methods from a technical point of view. But they do extend the functionality, so I call them extensions here.
FindChildByName Extension
This extension searches a child element in the visual tree by its name. Of course, there are other ways to find a control by its name, e.g. FrameworkElement.FindName
.
I needed to find a control that was created during runtime. I had a ListView
with an ItemsSource
bound to an ObservableCollection<T>
. An ItemTemplate
was defined, containing several controls. And I needed to access one particular control inside of this generated ListViewItem
. FrameworkElement.FindName
did not found it, even though a x:Name
was defined in the DataTemplate
.
This lead to the first extension.
// Implemented by VisualTreeHelperExtensions /// <summary> /// Searches a child element in the visual tree by its name. /// </summary> /// <param name="parent"> /// The parent of the element. /// </param> /// <param name="name"> /// The name of the child to search for. /// </param> /// <param name="child"> /// Set to the child if found, otherwise <c>null</c>. /// </param> /// <returns> /// <c>true</c> if the child was found, otherwise <c>false</c>. /// </returns> /// <remarks> /// This method walks the visual tree recursively! /// </remarks> public static bool FindChildByName ( DependencyObject parent, string name, out FrameworkElement child ) { // [Input parameter validation omitted] // Set the output first child = null; // Walk the tree int childrenCount = VisualTreeHelper.GetChildrenCount(parent); for (int childIndex = 0; childIndex < childrenCount; ++childIndex) { // Get the child DependencyObject childObject = VisualTreeHelper.GetChild(parent, childIndex); // Convert it into a framework element FrameworkElement childElement = childObject as FrameworkElement; // if successfull, check the name if (childElement != null && childElement.Name.Equals(name)) { // We found it child = childElement; // get out return (true); } // If the child contains the element, get out if (VisualTreeHelperExtensions .FindChildByName(childObject, name, out child)) { return (true); } } // if we got here, we hadn't found the child return (false); }
As you can see from the code, the class that implements this method is called VisualTreeHelperExtensions
. In case you like to use this extension too, make sure to give your extension class the same name. In case you want to give it another name, please change the call of VisualTreeHelperExtensions.FindChildByName
at the end of the method to TheNameOfYourClass.FindChildByName
.
FindFirstChildByType Extension
In another scenario, I needed to find the first child of a given type, independent from its name.
// Implemented by VisualTreeHelperExtensions /// <summary> /// Searches the first child element in the visual tree by its type. /// </summary> /// <param name="parent"> /// The parent of the element. /// </param> /// <param name="type"> /// The type of the child to search for. /// </param> /// <param name="child"> /// Set to the child if found, otherwise <c>null</c>. /// </param> /// <returns> /// <c>true</c> if the child was found, otherwise <c>false</c>. /// </returns> /// <remarks> /// This method walks the visual tree recursively! /// </remarks> public static bool FindFirstChildByType ( DependencyObject parent, Type type, out FrameworkElement child ) { // [Input parameter validation omitted] // Set the output first child = null; // Walk the tree int childrenCount = VisualTreeHelper.GetChildrenCount(parent); for (int childIndex = 0; childIndex < childrenCount; ++childIndex) { // Get the child DependencyObject childObject = VisualTreeHelper.GetChild(parent, childIndex); // Convert it into a framework element FrameworkElement childElement = childObject as FrameworkElement; // if successfull, check the type if (childElement != null && childElement.GetType() == type) { // We found it child = childElement; // get out return (true); } // If the child contains the element, get out if (VisualTreeHelperExtensions .FindFirstChildByType(childObject, type, out child)) { return (true); } } // if we got here, we hadn't found the child return (false); }
As said above, the class that implements this method is called VisualTreeHelperExtensions
. In case you like to use this extension too, make sure to give your extension class the same name. In case you want to give it another name, please change the call of VisualTreeHelperExtensions.FindChildByName
at the end of the method to TheNameOfYourClass.FindFirstChildByType
.
Links
VisualTreeHelper
class
Extension Methods (C# Programming Guide)