using System; using System.Collections.Generic; using System.Linq; using System.Windows; using System.Windows.Media; using System.Windows.Media.Media3D; namespace BPA.UIControl { /// /// form https://github.com/MaterialDesignInXAML/MaterialDesignInXamlToolkit /// MaterialDesignThemes.Wpf.Extensions /// public static class Extensions { public static IEnumerable VisualDepthFirstTraversal(this DependencyObject node) { if (node is null) throw new ArgumentNullException(nameof(node)); yield return node; for (var i = 0; i < VisualTreeHelper.GetChildrenCount(node); i++) { var child = VisualTreeHelper.GetChild(node, i); foreach (var descendant in child.VisualDepthFirstTraversal()) { yield return descendant; } } } public static IEnumerable VisualBreadthFirstTraversal(this DependencyObject node) { if (node is null) throw new ArgumentNullException(nameof(node)); for (var i = 0; i < VisualTreeHelper.GetChildrenCount(node); i++) { var child = VisualTreeHelper.GetChild(node, i); yield return child; } for (var i = 0; i < VisualTreeHelper.GetChildrenCount(node); i++) { var child = VisualTreeHelper.GetChild(node, i); foreach (var descendant in child.VisualDepthFirstTraversal()) { yield return descendant; } } } public static bool IsAncestorOf(this DependencyObject parent, DependencyObject node) => node != null && parent.VisualDepthFirstTraversal().Contains(node); /// /// Returns full visual ancestry, starting at the leaf. /// If element is not of or the /// logical ancestry is used. /// /// /// public static IEnumerable GetVisualAncestry(this DependencyObject leaf) { while (leaf != null) { yield return leaf; leaf = leaf is Visual || leaf is Visual3D ? VisualTreeHelper.GetParent(leaf) : LogicalTreeHelper.GetParent(leaf); } } public static IEnumerable GetLogicalAncestry(this DependencyObject leaf) { while (leaf != null) { yield return leaf; leaf = LogicalTreeHelper.GetParent(leaf); } } public static bool IsDescendantOf(this DependencyObject leaf, DependencyObject ancestor) { DependencyObject parent = null; foreach (var node in leaf.GetVisualAncestry()) { if (Equals(node, ancestor)) return true; parent = node; } return parent?.GetLogicalAncestry().Contains(ancestor) == true; } } }