Files
Shrlalgo.RvKits/Wpf.Ui.Extend/Extensions/VisualExtensions.cs
2024-09-22 11:05:41 +08:00

335 lines
12 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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
{
/// <summary>
/// 查找元素的子元素
/// </summary>
/// <typeparam name="T">子元素类型</typeparam>
/// <param name="obj"></param>
/// <returns></returns>
public static T FindVisualChild<T>(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<T>(child);
if (childOfChild != null)
return childOfChild;
}
}
return null;
}
/// <summary>
/// 得到指定元素的集合
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="depObj"></param>
/// <returns></returns>
public static IEnumerable<T> FindVisualChildren<T>(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<T>(child))
{
yield return childOfChild;
}
}
}
}
/// <summary>
/// 获取属性
/// </summary>
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;
}
/// <summary>
/// 利用visualtreehelper寻找对象的子级对象
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="obj"></param>
/// <returns></returns>
public static List<T> FindVisualChildrenEx<T>(this DependencyObject obj) where T : DependencyObject
{
try
{
List<T> 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<T>(child);
if (childOfChildren != null)
{
TList.AddRange(childOfChildren);
}
}
else
{
var childOfChildren = FindVisualChildrenEx<T>(child);
if (childOfChildren != null)
{
TList.AddRange(childOfChildren);
}
}
}
return TList;
}
catch
{
return null;
}
}
/// <summary>
/// 查找元素的父元素
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="i_dp"></param>
/// <returns></returns>
public static T FindParent<T>(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<T>(dobj);
if (dobj is not null and T)
{
return (T)dobj;
}
}
}
return null;
}
public static T FindParent<T>(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<T>(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;
}
/// <summary>
/// 查找指定名称的元素
/// </summary>
/// <typeparam name="childItem">元素类型</typeparam>
/// <param name="obj"></param>
/// <param name="elementName">元素名称及xaml中的Name</param>
/// <returns></returns>
public static childItem FindVisualElement<childItem>(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<childItem>(child).GetEnumerator();
while (j.MoveNext())
{
var childOfChild = (childItem)j.Current;
if (childOfChild != null && !(childOfChild as FrameworkElement).Name.Equals(elementName))
{
FindVisualElement<childItem>(childOfChild, elementName);
}
else
{
return childOfChild;
}
}
}
}
return null;
}
/// <summary>
/// 命中测试。根据当前选中元素,查找视觉树父节点与子节点,看是否存在指定类型的元素
/// </summary>
/// <typeparam name="T">想命中的元素类型</typeparam>
/// <param name="dp">当前选中元素</param>
/// <returns>true命中成功</returns>
public static bool HitTest<T>(this DependencyObject dp) where T : DependencyObject
{
return FindParent<T>(dp) != null || FindVisualChild<T>(dp) != null;
}
public static T FindEqualElement<T>(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<T>(child);
if (childOfChild != null)
{
return childOfChild;
}
}
}
return null;
}
/// <summary>
/// Gets the dependency property according to its name.
/// </summary>
/// <param name="type">The type.</param>
/// <param name="propertyName">Name of the property.</param>
/// <returns></returns>
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;
}
/// <summary>
/// Retrieves a <see cref="DependencyProperty"/> using reflection.
/// </summary>
/// <param name="o"></param>
/// <param name="propertyName"></param>
/// <returns></returns>
public static DependencyProperty GetDependencyProperty(this DependencyObject o, string propertyName)
{
DependencyProperty prop = null;
if (o != null)
{
prop = GetDependencyProperty(o.GetType(), propertyName);
}
return prop;
}
/// <summary>
/// 设置 <paramref name="property"/> 只有在没有明确设置的情况下才会使用。
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="o">The object.</param>
/// <param name="property">The property.</param>
/// <param name="value">The value.</param>
/// <returns></returns>
public static bool SetIfDefault<T>(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;
}
}
}