我正在从同一个应用程序中探索逻辑树和可视树,但没有成功深入各个级别。
我的代码使用通用资源管理器:
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
结果看起来很完整,但是当我尝试将 a 检索TextBlock
到GridViewColumn
Header 中时,看起来该项目既不存在于 Logical 中,也不存在于 Visual 的叶子列表中FrameworkElement
。
它似乎是一个视觉元素变成一个逻辑元素。事实上,添加一个手表,这TextBlock
出现在我的Visual Children中GridView
(检索为合乎逻辑,它处于Tab Item
未选中状态),但我的代码并非无法获取它。
我的电话很简单:
ProcessVisualTree(root, _visualElements);
ProcessLogicalTree(root, _logicalElements);
其中 root 是主窗口。
那么,我怎样才能在最深层次上探索我的树呢?也许重新遍历检索到的FrameworkElement
列表?我认为我的 ProcessGeneric 代码已经做到了。
更新:WPF Visualizer 显示了这种结构:
ListView > ScrollViewer > Grid > DockPanel > Grid > ScrollContentPresenter > GridViewHeaderRowPresenter > GridViewColumnHeader > HeaderBorder
该GridViewColumnHeader
级别包含我TextBlock
的,但视觉树不包含。
更新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工作正常。
我想知道它是否使用不同的方法来遍历树(也许也检查Properties
类似的方法Header
)。建议?