/// <summary> /// Retrieves all descendant elements of the specified type. /// </summary> public static List <T> GetChildrenOfType <T>(this DependencyObject element, VisualTreeFindFlags findFlags) where T : class { var descendants = new List <T>(); ForEachChildOfType <T>(element, findFlags, (T t) => { descendants.Add(t); return(VisualTreeForEachResult.Continue); }); return(descendants); }
/// <summary> /// Retrieves the first descendant element of the specified type (depth-first /// retrieval); may return the element itself unless otherwise specified. /// </summary> public static T GetFirstChildOfType <T>(this DependencyObject element, VisualTreeFindFlags findFlags) where T : class { var tWrapper = new Wrapper <T>(); ForEachChildOfType <T>(element, findFlags, (T t) => { tWrapper.Value = t; return(VisualTreeForEachResult.Stop); }); return(tWrapper.Value); }
/// <summary> /// Performs the specified operation for the ancestor element (if desired), as well as each /// descendant of the given type in the visual tree. /// </summary> public static VisualTreeForEachResult ForEachChildOfType <T>(this DependencyObject element, VisualTreeFindFlags findFlags, VisualTreeForEachTypedHandler <T> handler) where T : class { var result = VisualTreeForEachResult.Continue; bool skipCurrent = (findFlags & VisualTreeFindFlags.ExcludeCurrentElement) == VisualTreeFindFlags.ExcludeCurrentElement; findFlags &= ~VisualTreeFindFlags.ExcludeCurrentElement; T asT = null; if (!skipCurrent) { // Check if the element is of the supplied type asT = element as T; } if (asT != null) { result = handler(asT); } if (result == VisualTreeForEachResult.Continue) { var asDO = element as DependencyObject; if (asDO != null) { // Walk visual child list and look for more (recurse) int count = VisualTreeHelper.GetChildrenCount(asDO); for (int i = 0; i < count; i++) { var child = VisualTreeHelper.GetChild(asDO, i); result = ForEachChildOfType <T>(child, findFlags, handler); if (result == VisualTreeForEachResult.Stop) { break; } } } } if (result == VisualTreeForEachResult.SkipChildrenAndContinue) { result = VisualTreeForEachResult.Continue; } return(result); }