Visual Tree Helpers: Finding controls in the visual tree
Continuing with the theme of standing on the shoulders of those who came before us…
Today, I need to find a control “somewhere” in the visual tree. I found two different solutions to the issue. One finds child controls. The other finds ancestors. Since I copped the code from other sites (link in the comments section for each method) I won’t promise that everything works to perfection. I’ve used the FindVisualChildByName<T>() method in my code so my confidence is higher with that one.
Here’s the class I ended up with:
public static class VisualTreeHelpers { /// <summary> /// Find a named control in the visual tree where you have the parent control and need to find the child control. /// Found at: http://pwnedcode.wordpress.com/2009/04/01/find-a-control-in-a-wpfsilverlight-visual-tree-by-name/ /// </summary> /// <typeparam name="T">Control type you're looking for.</typeparam> /// <param name="parent">Known parent control.</param> /// <param name="name">Name of control you're looking for.</param> /// <returns>The target control or null.</returns> /// <example>var xamDockManager = VisualTreeHelpers.FindVisualChildByName<XamDockManager>(Application.Current.MainWindow, "XamDockManager1");</example> public static T FindVisualChildByName<T>(DependencyObject parent, string name) where T : DependencyObject { for (var i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++) { var child = VisualTreeHelper.GetChild(parent, i); var controlName = child.GetValue(Control.NameProperty) as string; if (controlName == name) return child as T; var result = FindVisualChildByName<T>(child, name); if (result != null) return result; } return null; } /// <summary> /// Find a named control in the visual tree where you have the child control and need to find the ancestor control. /// Found at: http://www.wpftutorial.net/LogicalAndVisualTree.html /// </summary> /// <typeparam name="T">Control type you're looking for.</typeparam> /// <param name="dependencyObject">The child control.</param> /// <returns>The target control or null.</returns> public static T FindAncestor<T>(DependencyObject dependencyObject) where T : class { var target = dependencyObject; do { target = VisualTreeHelper.GetParent(target); } while (target != null && !(target is T)); return target as T; } }
Notes:
My class name is a plural as to not conflict with the VisualTreeHelper from Microsoft.
I’m not happy with the magic-string for find the control name that gets passed in during the call, but that problem is outside the scope of this topic.
There’s always more to learn…
