逻辑树与可视化树
介绍
WPF用户界面的元素是层次相关的。这个关系被称作逻辑树。一个元素的模板由多个可视化元素组成,这棵树被称作可视化树。WPF区分这两棵树是因为,有些问题你只需要逻辑树,而其他问题你想要全部的元素。
<Window>
<Grid>
<Label Content="Lable" />
<Button Content="Button" />
</Grid>
</Window>
为什么我们需要两种不同的树
一个WPF控件由多个更原始的控件组成。一个按钮由边框,矩形和一个内容表示者组成。这些控件是按钮的可视化孩子。
当WPF渲染按钮时,元素本身没有外观,但它遍历可视化树并渲染它的可视化孩子。层次关系还可以用来做命中测试(?)或者布局等等。
但是有些时候你对控件模板的边框和矩形不感兴趣。特别是模板可以被替换,所以你不该关联到这个可视化树的结构。因为你想要仅包含真实的控件的更健壮的树,而不是所有的模板部分。这就是逻辑树的适用性。
逻辑树
逻辑树描述了用户界面的元素之间的关系。逻辑树负责:
- 继承依赖属性的值
- 解析动态资源引用
- 为绑定查找元素名
- 转发路由事件
可视化树
可视化树包含所有的逻辑元素包含每个元素的模板的可视化元素。可视化树负责:
- 渲染可视化元素
- 传播元素不透明度
- 传播布局和渲染变换(?)
- 传播IsEnabled属性
- 击中测试
- 相对资源(查找祖先)
用程序在可视化树中查找祖先
如果你有用户界面的孩子元素,并且你想要从父元素访问数据,但是你不知道元素在什么层级,最好的解决方案是向上查找直到找到请求类型的元素。
public static class VisualTreeHelperExtensions
{
public static T FindAncestor<T>(DependencyObject dependcyObject)
where T : class
{
DependencyObject target = dependencyObject;
do
{
target = VisualTreeHelper.GetParent(target);
}
while(target != null && !(target is T));
return target as T;
}
}
下列例子展示了如何使用这个帮助类。它从this开始向上查找可视化树,直到它找到一个类型为Grid的元素。如果这个帮助类到达了树的根,那么返回空。
var grid = VisualTreeHelperExtensions.FindAncestor<Grid>(this);

浙公网安备 33010602011771号