using System; using System.Collections; using System.Collections.Generic; using System.Reflection; using System.Windows; using System.Windows.Interop; using System.Windows.Media; namespace Wpf.Ui.Extend.Extensions { public static class VisualExtensions { /// /// 查找元素的子元素 /// /// 子元素类型 /// /// 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; } } } } /// /// 获取属性 /// 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; } /// /// 利用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; } } /// /// 查找元素的父元素 /// /// /// /// public static T FindParent(this DependencyObject i_dp) where T : DependencyObject { var dobj = (DependencyObject)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 = (DependencyObject)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 IntPtr GetHandle(this Visual visual) { return (PresentationSource.FromVisual(visual) as HwndSource)?.Handle ?? IntPtr.Zero; } /// /// 查找指定名称的元素 /// /// 元素类型 /// /// 元素名称,及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; } /// /// 命中测试。根据当前选中元素,查找视觉树父节点与子节点,看是否存在指定类型的元素 /// /// 想命中的元素类型 /// 当前选中元素 /// true:命中成功 public static bool HitTest(this DependencyObject dp) where T : DependencyObject { return FindParent(dp) != null || FindVisualChild(dp) != null; } 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 && child == element) { return (T)child; } else { var childOfChild = FindVisualChild(child); if (childOfChild != null) { 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; } /// /// 设置 只有在没有明确设置的情况下才会使用。 /// /// /// The object. /// The property. /// The value. /// public static bool SetIfDefault(this DependencyObject o, DependencyProperty property, T value) { if (o == null) throw new ArgumentNullException("o", "DependencyObject cannot be null"); if (property == null) throw new ArgumentNullException("property", "DependencyProperty cannot be null"); if (!property.PropertyType.IsAssignableFrom(typeof(T))) { throw new ArgumentException( string.Format("Expected {0} to be of type {1} but was {2}", property.Name, typeof(T).Name, property.PropertyType)); } if (DependencyPropertyHelper.GetValueSource(o, property).BaseValueSource == BaseValueSource.Default) { o.SetValue(property, value); return true; } return false; } } }