using System.Collections.Generic; using System.Windows; using System.Windows.Media; namespace DJ.Extensions { public static class DependencyObjectExtensions { /// /// Analyzes both visual and logical tree in order to find all elements of a given /// type that are descendants of the item. /// /// The type of the queried items. /// The root element that marks the source of the search. If the /// source is already of the requested type, it will not be included in the result. /// The UID of the /// All descendants of that match the requested type. public static T FindChildByUid(this DependencyObject source, string uid) where T : UIElement { if (source != null) { var childs = GetChildObjects(source); foreach (DependencyObject child in childs) { //analyze if children match the requested type if (child != null && child is T dependencyObject && dependencyObject.Uid.Equals(uid)) { return dependencyObject; } var descendant = FindChildByUid(child, uid); if (descendant != null) return descendant; } } return null; } /// /// This method is an alternative to WPF's /// method, which also /// supports content elements. Keep in mind that for content elements, /// this method falls back to the logical tree of the element. /// /// The item to be processed. /// The submitted item's child elements, if available. public static IEnumerable GetChildObjects(this DependencyObject parent) { if (parent == null) yield break; if (parent is ContentElement || parent is FrameworkElement) { //use the logical tree for content / framework elements foreach (object obj in LogicalTreeHelper.GetChildren(parent)) { var depObj = obj as DependencyObject; if (depObj != null) yield return (DependencyObject) obj; } } else { //use the visual tree per default int count = VisualTreeHelper.GetChildrenCount(parent); for (int i = 0; i < count; i++) { yield return VisualTreeHelper.GetChild(parent, i); } } } } }