我正在从同一个应用程序中探索逻辑和可视化树,但没有成功深入到各个级别 .
我的代码使用通用资源管理器:
private static void ProcessGenericTree(object current, List<FrameworkElement> leaves, Type treeType)
{
if (current is FrameworkElement)
{
if (!leaves.Contains(current as FrameworkElement))
leaves.Add(current as FrameworkElement);
}
DependencyObject dependencyObject = current as DependencyObject;
if (dependencyObject != null)
{
if (treeType.Equals(typeof(VisualTreeHelper)))
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(dependencyObject); i++)
{
ProcessVisualTree(VisualTreeHelper.GetChild(dependencyObject, i), leaves);
}
}
else
{
foreach (object child in LogicalTreeHelper.GetChildren(dependencyObject))
{
ProcessLogicalTree(child, leaves);
}
}
}
}
ProcessLogicalTree
和 ProcessVisualTree
简单地迭代(在 ProcessGenericTree
重新调用之前做一些事情) .
结果看起来很完整,但是当我试图将 TextBlock
检索到 GridViewColumn
Headers 时,看起来该项目既不存在于逻辑也不存在于 FrameworkElement
的Visual叶子列表中 .
它似乎是一个 Visual Element . 实际上添加一个 Watch TextBlock
出现在我的 GridView
的 Visual Children 中(检索为逻辑,它代表 Tab Item
未选中),但是我的代码无法得到它 .
我的电话非常简单:
ProcessVisualTree(root, _visualElements);
ProcessLogicalTree(root, _logicalElements);
其中root是MainWindow .
那么,我怎样才能在最深层探索我的树?也许重新遍历检索到的 FrameworkElement
列表?我认为我的ProcessGeneric代码已经完成了 .
Update :WPF Visualizer显示了这种结构:
ListView > ScrollViewer > Grid > DockPanel > Grid > ScrollContentPresenter > GridViewHeaderRowPresenter > GridViewColumnHeader > HeaderBorder
GridViewColumnHeader
级别包含我的 TextBlock
但视觉树没有 .
Update 2 :使用从主窗口开始的递归,我的元素可见我无法使用以下代码查找具有指定名称的对象:
public static T FindVisualChild<T>(DependencyObject depObj) where T : DependencyObject
{
if (depObj != null)
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
{
DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
if (child != null && child is T)
{
return (T)child;
}
T childItem = FindVisualChild<T>(child);
if (childItem != null) return childItem;
}
}
return null;
}
我很确定 VisualTreeHelper
无法检索Header属性中的元素,但WPF Inspector正常工作 .
我想知道它是否使用不同的方法来遍历树(也许像 Header
那样检查 Properties
) . 建议?