一、查找子元素的方法:
#region Functions.Visual.Child
/// <summary>
/// 枚举:搜索子元素模式
/// </summary>
public enum FindChildrenMode
{
/// <summary> 只限于根层元素 </summary>
ROOT = 0,
/// <summary> 按分支顺序 </summary>
BRANCH = 1,
/// <summary> 按层的顺序 </summary>
LAYER = 2,
}
#endregion
#region Functions.Visual.Child
/// <summary>
/// Get:获取符合类型的迭代
/// </summary>
/// <typeparam name="T">查找的类型</typeparam>
/// <param name="visual">查找的元素</param>
/// <param name="mode">搜索子元素模式</param>
/// <param name="isSearchT">搜索对象是否包括T元素</param>
/// <returns></returns>
public static IEnumerable<T> GetChildrenEnumerable<T>(DependencyObject visual, FindChildrenMode mode, bool isSearchT = true)
where T : FrameworkElement
{
if (visual == null) { yield break; }
var _count = VisualTreeHelper.GetChildrenCount(visual);
switch (mode)
{
case FindChildrenMode.ROOT:
{
#region ROOT
for (int i = 0; i < _count; i++)
{
var _child = VisualTreeHelper.GetChild(visual, i);
if (_child == null) { continue; }
if (_child is T _target)
{
yield return _target;
}
}
#endregion
}
break;
case FindChildrenMode.BRANCH:
{
#region BRANCH
for (int i = 0; i < _count; i++)
{
var _child = VisualTreeHelper.GetChild(visual, i);
if (_child == null) { continue; }
if (_child is T _target)
{
yield return _target;
if (!isSearchT) { continue; }
}
var _enumerable = GetChildrenEnumerable<T>(_child, mode, isSearchT);
foreach (T _sub in _enumerable)
{
yield return _sub;
}
}
#endregion
}
break;
case FindChildrenMode.LAYER:
{
#region BRANCH
for (int i = 0; i < _count; i++)
{
var _child = VisualTreeHelper.GetChild(visual, i);
if (_child == null) { continue; }
if (_child is T _target)
{
yield return _target;
}
}
for (int i = 0; i < _count; i++)
{
var _child = VisualTreeHelper.GetChild(visual, i);
if (_child == null) { continue; }
if (!isSearchT)
{
if (_child is T) { continue; }
}
var _enumerable = GetChildrenEnumerable<T>(_child, mode, isSearchT);
foreach (T _sub in _enumerable)
{
yield return _sub;
}
}
#endregion
}
break;
}
}
/// <summary>
/// Get:获取符合类型的迭代
/// </summary>
/// <typeparam name="T">查找的类型</typeparam>
/// <param name="visual">查找的元素</param>
/// <returns></returns>
public static IEnumerable<T> GetChildrenEnumerable<T>(DependencyObject visual)
where T : FrameworkElement
{
return GetChildrenEnumerable<T>(visual, FindChildrenMode.LAYER, true);
}
/// <summary>
/// Get:获取所有符合类型的子元素
/// </summary>
/// <typeparam name="T">查找的类型</typeparam>
/// <param name="visual">查找的元素</param>
/// <returns></returns>
public static List<T> FindAllChild<T>(DependencyObject visual)
where T : FrameworkElement
{
var _list = new List<T>();
if (visual == null) { return _list; }
var _enumerable = GetChildrenEnumerable<T>(visual);
_list.AddRange(_enumerable);
return _list;
}
/// <summary>
/// Get:获取首个符合类型的子元素
/// </summary>
/// <typeparam name="T">查找的类型</typeparam>
/// <param name="visual">查找的元素</param>
/// <returns></returns>
public static T FirstChild<T>(DependencyObject visual)
where T : FrameworkElement
{
if (visual == null) { return default; }
var _enumerable = GetChildrenEnumerable<T>(visual);
foreach (var _child in _enumerable)
{
if (_child == null) { continue; }
return _child;
}
return default;
}
/// <summary>
/// Get:获取首个符合类型的子元素
/// </summary>
/// <typeparam name="T">查找的类型</typeparam>
/// <param name="visual">查找的元素</param>
/// <param name="name">元素名称</param>
/// <returns></returns>
public static T FirstChild<T>(DependencyObject visual, string name)
where T : FrameworkElement
{
if (visual == null) { return default; }
var _enumerable = GetChildrenEnumerable<T>(visual);
foreach (var _child in _enumerable)
{
if (_child == null) { continue; }
if (_child.Name == name) { return _child; }
}
return default;
}
#endregion
二、查找父元素的方法:
#region Functions.Visual.Parent
/// <summary>
/// Get:获取符合类型的父元素
/// </summary>
/// <typeparam name="T">父控件的类型</typeparam>
/// <param name="visual">要找的是obj的父控件</param>
/// <returns>目标父控件</returns>
public static T GetParent<T>(DependencyObject visual)
where T : FrameworkElement
{
if (visual == null) { return default; }
var _parent = VisualTreeHelper.GetParent(visual);
while (_parent != null)
{
if (_parent is T _pVisual) { return _pVisual; }
// 在上一级父控件中没有找到指定名字的控件,就再往上一级找
_parent = VisualTreeHelper.GetParent(_parent);
}
return default;
}
/// <summary>
/// Get:获取符合类型的父元素
/// </summary>
/// <typeparam name="T">父控件的类型</typeparam>
/// <param name="visual">要找的是obj的父控件</param>
/// <param name="name">想找的父控件的Name属性</param>
/// <returns>目标父控件</returns>
public static T GetParent<T>(Visual visual, string name)
where T : FrameworkElement
{
if (visual == null) { return default; }
var _parent = VisualTreeHelper.GetParent(visual);
while (_parent != null)
{
if (_parent is T _pVisual)
{
if (_pVisual.Name == name)
{
return _pVisual;
}
}
// 在上一级父控件中没有找到指定名字的控件,就再往上一级找
_parent = VisualTreeHelper.GetParent(_parent);
}
return default;
}
#endregion