/// <summary> /// Finds the first child of this <see cref="DependencyObject" /> matching the specified type and satisfying a specified condition by traversing either the visual or the logical tree recursively. If no child was found, <see langword="null" /> is returned. /// </summary> /// <typeparam name="T">The explicit type of the children to search for.</typeparam> /// <param name="dependencyObject">The <see cref="DependencyObject" /> to traverse the tree recursively.</param> /// <param name="treeType">A <see cref="UITreeType" /> value indicating whether to use the <see cref="LogicalTreeHelper" /> or the <see cref="VisualTreeHelper" />.</param> /// <param name="predicate">The <see cref="Predicate{T}" /> that determines whether the child is included in the result.</param> /// <returns> /// The first child of the specified type that satisfies a specified condition, depending on <paramref name="treeType" />, that can be casted to <typeparamref name="T" />. If no child was found, <see langword="null" /> is returned. /// </returns> public static T FindChild <T>(this DependencyObject dependencyObject, UITreeType treeType, Predicate <T> predicate) where T : DependencyObject { Check.ArgumentNull(dependencyObject, nameof(dependencyObject)); Check.ArgumentNull(predicate, nameof(predicate)); IEnumerable <DependencyObject> children = treeType switch { UITreeType.Logical => LogicalTreeHelper.GetChildren(dependencyObject).OfType <DependencyObject>(), UITreeType.Visual => Create.Enumerable(VisualTreeHelper.GetChildrenCount(dependencyObject), i => VisualTreeHelper.GetChild(dependencyObject, i)), _ => throw Throw.InvalidEnumArgument(nameof(treeType), treeType) }; foreach (DependencyObject child in children) { if (child is T convertedChild && predicate(convertedChild)) { return(convertedChild); }
/// <summary> /// Tries to find the closest parent of this <see cref="DependencyObject" /> matching the specified type and satisfying a specified condition by traversing either the visual or the logical tree. /// </summary> /// <typeparam name="T">The explicit type of the parent to search for.</typeparam> /// <param name="dependencyObject">The <see cref="DependencyObject" /> to traverse the tree from.</param> /// <param name="treeType">A <see cref="UITreeType" /> value indicating whether to use the <see cref="LogicalTreeHelper" /> or the <see cref="VisualTreeHelper" />.</param> /// <param name="predicate">The <see cref="Predicate{T}" /> that determines whether the parent of the specified type is returned.</param> /// <returns> /// The closest visual or logical parent of this <see cref="DependencyObject" />, depending on <paramref name="treeType" /> and <paramref name="predicate" />, that is of type <typeparamref name="T" />, if found; /// otherwise, <see langword="null" />. /// </returns> public static T FindParent <T>(this DependencyObject dependencyObject, UITreeType treeType, Predicate <T> predicate) where T : DependencyObject { Check.ArgumentNull(dependencyObject, nameof(dependencyObject)); if (dependencyObject is Visual) { DependencyObject parent = treeType switch { UITreeType.Logical => LogicalTreeHelper.GetParent(dependencyObject), UITreeType.Visual => VisualTreeHelper.GetParent(dependencyObject), _ => throw Throw.InvalidEnumArgument(nameof(treeType), treeType) }; return(parent is T visualParent && predicate?.Invoke(visualParent) != false ? visualParent : parent?.FindParent <T>(treeType, predicate)); } else { return(null); } }
/// <summary> /// Finds all children of this <see cref="DependencyObject" /> matching the specified type and satisfying a specified condition by traversing either the visual or the logical tree recursively. If no children have been found, an empty array is returned. /// </summary> /// <typeparam name="T">The explicit type of the children to search for.</typeparam> /// <param name="dependencyObject">The <see cref="DependencyObject" /> to traverse the tree recursively.</param> /// <param name="treeType">A <see cref="UITreeType" /> value indicating whether to use the <see cref="LogicalTreeHelper" /> or the <see cref="VisualTreeHelper" />.</param> /// <param name="predicate">The <see cref="Predicate{T}" /> that determines whether the child is included in the result.</param> /// <returns> /// An array of the specified type with all children, depending on <paramref name="treeType" /> and <paramref name="predicate" />, that can be casted to <typeparamref name="T" />. If no children have been found, an empty array is returned. /// </returns> public static T[] FindChildren <T>(this DependencyObject dependencyObject, UITreeType treeType, Predicate <T> predicate) where T : DependencyObject { Check.ArgumentNull(dependencyObject, nameof(dependencyObject)); List <T> result = new List <T>(); IEnumerable <DependencyObject> children = treeType switch { UITreeType.Logical => children = LogicalTreeHelper.GetChildren(dependencyObject).OfType <DependencyObject>(), UITreeType.Visual => children = Create.Enumerable(VisualTreeHelper.GetChildrenCount(dependencyObject), i => VisualTreeHelper.GetChild(dependencyObject, i)), _ => throw Throw.InvalidEnumArgument(nameof(treeType), treeType) }; foreach (DependencyObject child in children) { if (child is T convertedChild && predicate?.Invoke(convertedChild) != false) { result.Add(convertedChild); } result.AddRange(child.FindChildren(treeType, predicate)); } return(result.ToArray()); }
/// <summary> /// Tries to find the closest parent of this <see cref="DependencyObject" /> matching the specified type by traversing either the visual or the logical tree. /// </summary> /// <typeparam name="T">The explicit type of the parent to search for.</typeparam> /// <param name="dependencyObject">The <see cref="DependencyObject" /> to traverse the tree from.</param> /// <param name="treeType">A <see cref="UITreeType" /> value indicating whether to use the <see cref="LogicalTreeHelper" /> or the <see cref="VisualTreeHelper" />.</param> /// <returns> /// The closest visual or logical parent of this <see cref="DependencyObject" />, depending on <paramref name="treeType" />, that is of type <typeparamref name="T" />, if found; /// otherwise, <see langword="null" />. /// </returns> public static T FindParent <T>(this DependencyObject dependencyObject, UITreeType treeType) where T : DependencyObject { return(dependencyObject.FindParent <T>(treeType, null)); }
/// <summary> /// Returns an array with all parents of this <see cref="DependencyObject" /> matching the specified type by traversing either the visual or the logical tree. /// </summary> /// <param name="dependencyObject">The <see cref="DependencyObject" /> to traverse the tree from.</param> /// <param name="treeType">A <see cref="UITreeType" /> value indicating whether to use the <see cref="LogicalTreeHelper" /> or the <see cref="VisualTreeHelper" />.</param> /// <returns> /// An array with all parents of this <see cref="DependencyObject" />, depending on <paramref name="treeType" />. /// </returns> public static DependencyObject[] GetParents(this DependencyObject dependencyObject, UITreeType treeType) { Check.ArgumentNull(dependencyObject, nameof(dependencyObject)); List <DependencyObject> result = new List <DependencyObject>(); while (dependencyObject != null) { DependencyObject parent; switch (treeType) { case UITreeType.Logical: parent = LogicalTreeHelper.GetParent(dependencyObject); break; case UITreeType.Visual: parent = VisualTreeHelper.GetParent(dependencyObject); break; default: throw Throw.InvalidEnumArgument(nameof(treeType), treeType); } if (parent != null) { result.Add(parent); } dependencyObject = parent; } return(result.ToArray()); }
/// <summary> /// Finds all children of this <see cref="DependencyObject" /> matching the specified type by traversing either the visual or the logical tree recursively. If no children have been found, an empty array is returned. /// </summary> /// <typeparam name="T">The explicit type of the children to search for.</typeparam> /// <param name="dependencyObject">The <see cref="DependencyObject" /> to traverse the tree recursively.</param> /// <param name="treeType">A <see cref="UITreeType" /> value indicating whether to use the <see cref="LogicalTreeHelper" /> or the <see cref="VisualTreeHelper" />.</param> /// <returns> /// An array of the specified type with all children, depending on <paramref name="treeType" />, that can be casted to <typeparamref name="T" />. If no children have been found, an empty array is returned. /// </returns> public static T[] FindChildren <T>(this DependencyObject dependencyObject, UITreeType treeType) where T : DependencyObject { return(dependencyObject.FindChildren <T>(treeType, null)); }