优化更新代码,添加界面功能并整合
This commit is contained in:
290
WPFluent/Controls/Primitives/VisualTree.cs
Normal file
290
WPFluent/Controls/Primitives/VisualTree.cs
Normal file
@@ -0,0 +1,290 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace WPFluent.Controls.Primitives;
|
||||
|
||||
public static class VisualTree
|
||||
{
|
||||
public static FrameworkElement? FindDescendantByName(this DependencyObject element, string name)
|
||||
{
|
||||
if (element == null || string.IsNullOrWhiteSpace(name))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (name.Equals((element as FrameworkElement)?.Name, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return element as FrameworkElement;
|
||||
}
|
||||
|
||||
var childrenCount = VisualTreeHelper.GetChildrenCount(element);
|
||||
for (var i = 0; i < childrenCount; i++)
|
||||
{
|
||||
var frameworkElement = VisualTreeHelper.GetChild(element, i).FindDescendantByName(name);
|
||||
if (frameworkElement != null)
|
||||
{
|
||||
return frameworkElement;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static T? FindDescendant<T>(this DependencyObject element) where T : DependencyObject
|
||||
{
|
||||
T? val = null;
|
||||
var childrenCount = VisualTreeHelper.GetChildrenCount(element);
|
||||
for (var i = 0; i < childrenCount; i++)
|
||||
{
|
||||
var child = VisualTreeHelper.GetChild(element, i);
|
||||
if (child is T val2)
|
||||
{
|
||||
val = val2;
|
||||
break;
|
||||
}
|
||||
|
||||
val = child.FindDescendant<T>();
|
||||
if (val != null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
public static object? FindDescendant(this DependencyObject element, Type type)
|
||||
{
|
||||
object? obj = null;
|
||||
var childrenCount = VisualTreeHelper.GetChildrenCount(element);
|
||||
for (var i = 0; i < childrenCount; i++)
|
||||
{
|
||||
var child = VisualTreeHelper.GetChild(element, i);
|
||||
if (child.GetType() == type)
|
||||
{
|
||||
obj = child;
|
||||
break;
|
||||
}
|
||||
|
||||
obj = child.FindDescendant(type);
|
||||
if (obj != null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
public static IEnumerable<T> FindDescendants<T>(this DependencyObject element) where T : DependencyObject
|
||||
{
|
||||
var childrenCount = VisualTreeHelper.GetChildrenCount(element);
|
||||
for (var i = 0; i < childrenCount; i++)
|
||||
{
|
||||
var child = VisualTreeHelper.GetChild(element, i);
|
||||
if (child is T val)
|
||||
{
|
||||
yield return val;
|
||||
}
|
||||
|
||||
foreach (var item in child.FindDescendants<T>())
|
||||
{
|
||||
yield return item;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static FrameworkElement? FindAscendantByName(this DependencyObject element, string name)
|
||||
{
|
||||
if (element == null || string.IsNullOrWhiteSpace(name))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var parent = VisualTreeHelper.GetParent(element);
|
||||
if (parent == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (name.Equals((parent as FrameworkElement)?.Name, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return parent as FrameworkElement;
|
||||
}
|
||||
|
||||
return parent.FindAscendantByName(name);
|
||||
}
|
||||
|
||||
public static T? FindAscendant<T>(this DependencyObject element) where T : DependencyObject
|
||||
{
|
||||
var parent = VisualTreeHelper.GetParent(element);
|
||||
if (parent == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (parent is T)
|
||||
{
|
||||
return parent as T;
|
||||
}
|
||||
|
||||
return parent.FindAscendant<T>();
|
||||
}
|
||||
|
||||
public static object? FindAscendant(this DependencyObject element, Type type)
|
||||
{
|
||||
var parent = VisualTreeHelper.GetParent(element);
|
||||
if (parent == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (parent.GetType() == type)
|
||||
{
|
||||
return parent;
|
||||
}
|
||||
|
||||
return parent.FindAscendant(type);
|
||||
}
|
||||
|
||||
public static IEnumerable<DependencyObject> FindAscendants(this DependencyObject element)
|
||||
{
|
||||
for (var parent = VisualTreeHelper.GetParent(element); parent != null; parent = VisualTreeHelper.GetParent(parent))
|
||||
{
|
||||
yield return parent;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool DetachFromParent(this FrameworkElement element, DependencyObject parent)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (parent is Panel panel)
|
||||
{
|
||||
panel.Children.Remove(element);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (parent is Decorator decorator)
|
||||
{
|
||||
if (decorator.Child == element)
|
||||
{
|
||||
decorator.Child = null;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (parent is ContentControl contentControl)
|
||||
{
|
||||
contentControl.Content = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (parent is ContentPresenter contentPresenter)
|
||||
{
|
||||
contentPresenter.Content = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (parent is Popup popup)
|
||||
{
|
||||
popup.Child = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (parent is ItemsControl itemsControl)
|
||||
{
|
||||
if (itemsControl.Items.Contains(element))
|
||||
{
|
||||
itemsControl.Items.Remove(element);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (itemsControl.Items.Contains(element.DataContext))
|
||||
{
|
||||
itemsControl.Items.Remove(element.DataContext);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var type = parent.GetType();
|
||||
var bindingAttr = BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Public;
|
||||
List<PropertyInfo> obj =
|
||||
[
|
||||
type.GetProperty("Children", bindingAttr),
|
||||
type.GetProperty("Child", bindingAttr),
|
||||
type.GetProperty("Content", bindingAttr),
|
||||
type.GetProperty("Items", bindingAttr)
|
||||
];
|
||||
var flag = false;
|
||||
foreach (var item in obj)
|
||||
{
|
||||
switch (item.Name.ToLower())
|
||||
{
|
||||
case "children":
|
||||
{
|
||||
var value = item.GetValue(parent, null);
|
||||
var methods = value?.GetType().GetMethods() ?? [];
|
||||
foreach (var methodInfo in methods)
|
||||
{
|
||||
if (methodInfo.Name.ToLower() == "remove")
|
||||
{
|
||||
methodInfo.Invoke(value, [element]);
|
||||
flag = true;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case "child":
|
||||
case "content":
|
||||
if (item.GetValue(parent) == element)
|
||||
{
|
||||
item.SetValue(parent, null);
|
||||
flag = true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (flag)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
if (Debugger.IsAttached)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool DetachFromLogicalParent(this FrameworkElement element)
|
||||
{
|
||||
var parent = element.Parent;
|
||||
element.DetachFromParent(parent);
|
||||
return element.Parent != parent;
|
||||
}
|
||||
|
||||
public static bool DetachFromVisualParent(this FrameworkElement element)
|
||||
{
|
||||
var parent = VisualTreeHelper.GetParent(element);
|
||||
element.DetachFromParent(parent);
|
||||
return VisualTreeHelper.GetParent(element) != parent;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user