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;
}
}
}