using System; using System.Collections; using System.Reflection; namespace WPFluent.Extensions { public static class VisualExtensions { public static T FindEqualElement(DependencyObject source, DependencyObject element) where T : DependencyObject { for (var i = 0; i < VisualTreeHelper.GetChildrenCount(source); i++) { var child = VisualTreeHelper.GetChild(source, i); if (child != null && child is T t && child == element) { return t; } else { var childOfChild = FindVisualChild(child); if (childOfChild != null) { return childOfChild; } } } return null; } /// /// 查找元素的父元素 /// /// /// /// public static T FindParent(this DependencyObject i_dp) where T : DependencyObject { var dobj = VisualTreeHelper.GetParent(i_dp); if (dobj != null) { if (dobj is T t) { return t; } else { dobj = FindParent(dobj); if (dobj is not null and T) { return (T)dobj; } } } return null; } public static T FindParent(this DependencyObject i_dp, string elementName) where T : DependencyObject { var dobj = VisualTreeHelper.GetParent(i_dp); if (dobj != null) { if (dobj is T && ((System.Windows.FrameworkElement)(dobj)).Name.Equals(elementName)) { return (T)dobj; } else { dobj = FindParent(dobj); if (dobj is not null and T) { return (T)dobj; } } } return null; } /// /// 查找元素的子元素 /// /// 子元素类型 /// /// public static T FindVisualChild(this DependencyObject obj) where T : DependencyObject { for (var i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++) { var child = VisualTreeHelper.GetChild(obj, i); if (child is not null and T) return (T)child; else { var childOfChild = FindVisualChild(child); if (childOfChild != null) return childOfChild; } } return null; } /// /// 得到指定元素的集合 /// /// /// /// public static IEnumerable FindVisualChildren(this DependencyObject depObj) where T : DependencyObject { if (depObj != null) { for (var i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++) { var child = VisualTreeHelper.GetChild(depObj, i); if (child is not null and T) { yield return (T)child; } foreach (var childOfChild in FindVisualChildren(child)) { yield return childOfChild; } } } } /// /// 利用visualtreehelper寻找对象的子级对象 /// /// /// /// public static List FindVisualChildrenEx(this DependencyObject obj) where T : DependencyObject { try { List TList = []; for (var i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++) { var child = VisualTreeHelper.GetChild(obj, i); if (child is not null and T) { TList.Add((T)child); var childOfChildren = FindVisualChildrenEx(child); if (childOfChildren != null) { TList.AddRange(childOfChildren); } } else { var childOfChildren = FindVisualChildrenEx(child); if (childOfChildren != null) { TList.AddRange(childOfChildren); } } } return TList; } catch { return null; } } /// /// 查找指定名称的元素 /// /// 元素类型 /// /// 元素名称,及xaml中的Name /// public static childItem FindVisualElement(this DependencyObject obj, string elementName) where childItem : DependencyObject { for (var i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++) { var child = VisualTreeHelper.GetChild(obj, i); if (child != null && child is childItem && ((System.Windows.FrameworkElement)(child)).Name.Equals(elementName)) return (childItem)child; else { IEnumerator j = FindVisualChildren(child).GetEnumerator(); while (j.MoveNext()) { var childOfChild = (childItem)j.Current; if (childOfChild != null && !(childOfChild as FrameworkElement).Name.Equals(elementName)) { FindVisualElement(childOfChild, elementName); } else { return childOfChild; } } } } return null; } /// /// Gets the dependency property according to its name. /// /// The type. /// Name of the property. /// public static DependencyProperty GetDependencyProperty(Type type, string propertyName) { DependencyProperty prop = null; if (type != null) { var fieldInfo = type.GetField($"{propertyName}Property", BindingFlags.Static | BindingFlags.Public); if (fieldInfo != null) { prop = fieldInfo.GetValue(null) as DependencyProperty; } } return prop; } /// /// Retrieves a using reflection. /// /// /// /// public static DependencyProperty GetDependencyProperty(this DependencyObject o, string propertyName) { DependencyProperty prop = null; if (o != null) { prop = GetDependencyProperty(o.GetType(), propertyName); } return prop; } public static IntPtr GetHandle(this Visual visual) { return (PresentationSource.FromVisual(visual) as HwndSource)?.Handle ?? IntPtr.Zero; } /// /// 获取属性 /// public static object GetPropertyValue(this object obj, string path) { if (obj == null) return string.Empty; var flag = !string.IsNullOrEmpty(path); object result; if (flag) { var property = obj.GetType().GetProperty(path); var flag2 = property != null; if (flag2) { try { result = property.GetValue(obj, null); return result; } catch { try { var type = obj.GetType(); var mInfo = type.GetMethod($"get_{path}"); if (mInfo != null) { result = mInfo.Invoke(obj, null); return result; } } catch { } } } } result = obj; return result; } /// /// 命中测试。根据当前选中元素,查找视觉树父节点与子节点,看是否存在指定类型的元素 /// /// 想命中的元素类型 /// 当前选中元素 /// true:命中成功 public static bool HitTest(this DependencyObject dp) where T : DependencyObject { return FindParent(dp) != null || FindVisualChild(dp) != null; } /// /// 设置 只有在没有明确设置的情况下才会使用。 /// /// /// The object. /// The property. /// The value. /// public static bool SetIfDefault(this DependencyObject o, DependencyProperty property, T value) { if (o == null) throw new ArgumentNullException(nameof(o), "DependencyObject cannot be null"); if (property == null) throw new ArgumentNullException(nameof(property), "DependencyProperty cannot be null"); if (!property.PropertyType.IsAssignableFrom(typeof(T))) { throw new ArgumentException( $"Expected {property.Name} to be of type {typeof(T).Name} but was {property.PropertyType}"); } if (DependencyPropertyHelper.GetValueSource(o, property).BaseValueSource == BaseValueSource.Default) { o.SetValue(property, value); return true; } return false; } } }