using System; using System.Collections.Generic; using System.Windows; using System.Windows.Media; namespace Xamarin.PropertyEditing.Windows { internal static class XamlHelper { public static IEnumerable GetDescendants (this UIElement self) where T : UIElement { if (self == null) throw new ArgumentNullException (nameof (self)); var childCount = VisualTreeHelper.GetChildrenCount (self); for (var i = 0; i < childCount; i++) { if (VisualTreeHelper.GetChild (self, i) is UIElement child) { if (child is T correctlyTypedChild) yield return correctlyTypedChild; IEnumerable grandChildren = GetDescendants (child); foreach (T grandChild in grandChildren) yield return grandChild; } } } public static T FindParent (this UIElement self) where T : UIElement { UIElement parent = VisualTreeHelper.GetParent (self) as UIElement; if (parent == null) return default(T); return parent.FindParentOrSelf(); } public static FrameworkElement FindPropertiesHost (this FrameworkElement self) { DependencyObject parent = self; while (!(parent is IPropertiesHost) && parent != null) { parent = VisualTreeHelper.GetParent (parent); } return (FrameworkElement)parent; } public static T FindParentOrSelf (this UIElement self) where T : UIElement { if (self == null) throw new ArgumentNullException (nameof (self)); DependencyObject parent = self; while (!(parent is T) && parent != null) { parent = VisualTreeHelper.GetParent (parent); } return (T)parent; } public static TParent FindParentUnless (this UIElement self) where TParent : UIElement where TUnless : UIElement { if (self == null) throw new ArgumentNullException (nameof (self)); DependencyObject parent = VisualTreeHelper.GetParent (self); while (!(parent is TParent) && parent != null) { if (parent is TUnless) return default(TParent); parent = VisualTreeHelper.GetParent (parent); } return (TParent)parent; } } }