/// <summary> /// Returns all the child visual objects within this parent that satisfies a condition. /// </summary> /// <param name="parent">The parent visual whose children to look through.</param> /// <param name="predicate">A function to test each visual for a condition.</param> /// <param name="treeTraverseStrategy">The strategy to use.</param> public static IEnumerable <Visual> GetVisualChildCollection(this Visual parent, Func <Visual, bool> predicate, TreeTraverseStrategy treeTraverseStrategy = TreeTraverseStrategy.BreadthFirst) { ICollection visuals; switch (treeTraverseStrategy) { case TreeTraverseStrategy.BreadthFirst: visuals = new Queue <Visual>(); ((Queue <Visual>)visuals).Enqueue(parent); break; case TreeTraverseStrategy.DepthFirst: visuals = new Stack <Visual>(); ((Stack <Visual>)visuals).Push(parent); break; default: throw new NotImplementedException($"Uknown TreeTraverseStrategy: '{treeTraverseStrategy}'."); } bool firstTime = true; while (visuals.Count > 0) { Visual visual; switch (treeTraverseStrategy) { case TreeTraverseStrategy.BreadthFirst: visual = ((Queue <Visual>)visuals).Dequeue(); break; case TreeTraverseStrategy.DepthFirst: visual = ((Stack <Visual>)visuals).Pop(); break; default: throw new NotImplementedException($"Uknown TreeTraverseStrategy: '{treeTraverseStrategy}'."); } if (firstTime) { // parent should not be tested because it is not a child firstTime = false; } else if (predicate(visual)) { yield return(visual); } int childrenCount = VisualTreeHelper.GetChildrenCount(visual); for (int i = childrenCount - 1; i >= 0; --i) { DependencyObject child = VisualTreeHelper.GetChild(visual, i); if (!(child is Visual childVisual)) { continue; } switch (treeTraverseStrategy) { case TreeTraverseStrategy.BreadthFirst: ((Queue <Visual>)visuals).Enqueue(childVisual); break; case TreeTraverseStrategy.DepthFirst: ((Stack <Visual>)visuals).Push(childVisual); break; default: throw new NotImplementedException($"Uknown TreeTraverseStrategy: '{treeTraverseStrategy}'."); } } } }
/// <summary> /// Returns all the child visual objects of the specified generic types within the specified parent. /// </summary> /// <typeparam name="T1">The first type of visuals to search for.</typeparam> /// <typeparam name="T2">The second type of visuals to search for.</typeparam> /// <param name="parent">The parent visual whose children to look through.</param> /// <param name="treeTraverseStrategy">The strategy to use.</param> public static IEnumerable <Visual> GetVisualChildCollection <T1, T2>(this Visual parent, TreeTraverseStrategy treeTraverseStrategy = TreeTraverseStrategy.BreadthFirst) where T1 : Visual where T2 : Visual { return(GetVisualChildCollection(parent, new List <Type>() { typeof(T1), typeof(T2) }, treeTraverseStrategy)); }
/// <summary> /// Returns all the child visual objects of the specified types within the specified parent. /// </summary> /// <param name="parent">The parent visual whose children to look through.</param> /// <param name="typesOfChildren">The types of visuals to search for. All the types should be child types of <see cref="Visual"/>.</param> /// <param name="treeTraverseStrategy">The strategy to use.</param> public static IEnumerable <Visual> GetVisualChildCollection(this Visual parent, IEnumerable <Type> typesOfChildren, TreeTraverseStrategy treeTraverseStrategy = TreeTraverseStrategy.BreadthFirst) { return(GetVisualChildCollection(parent, (Visual v) => { Type childType = v.GetType(); return typesOfChildren.Any(type => type.IsAssignableFrom(childType)); }, treeTraverseStrategy)); }
/// <summary> /// Returns all the child visual objects of the specified visual type within the specified parent. /// </summary> /// <typeparam name="T">The type of visuals to search for.</typeparam> /// <param name="parent">The parent visual whose children to look through.</param> /// <param name="treeTraverseStrategy">The strategy to use.</param> public static IEnumerable <T> GetVisualChildCollection <T>(this Visual parent, TreeTraverseStrategy treeTraverseStrategy = TreeTraverseStrategy.BreadthFirst) where T : Visual { return(GetVisualChildCollection(parent, new List <Type>() { typeof(T) }, treeTraverseStrategy).Cast <T>()); }