WPF 中的逻辑树(Logical Tree)与可视化元素树(Visual Tree)
一、前言
WPF 中有两种“树”:逻辑树(Logical Tree)和可视化元素树(Visual Tree)。 Logical Tree 最显著的特点就是它完全由布局组件和控件组成。那么 Visual Tree 是什么呢?
如果我们仔细观察一棵树的树叶,会发现树叶的脉络也像一棵“树”——有自己的基部并向上生长出多级分叉。在 WPF 的 Logical Tree 上,充当“树叶”的一般都是控件,如果我们仔细观察控件,会发现 WPF 控件本身也是一颗由更细微级别的组件(它们不是控件,而是一些可视化组件,派生自 Visual 类)组成的“树”。即当我们把 Logical Tree 延伸至控件的模板(Template)组件级别时,我们得到的就是 Visual Tree。
实际工作中,大多数情况下我们都是在与 Lgical Tree 打交道,如果你的程序需要借助 Visual Tree 来完成一些与业务逻辑(而不是纯表现逻辑)相关的功能,多半是程序设计不良造成的,最好重新考虑逻辑、功能和数据类型方面的设计。
二、两棵“树”的操作
如果在 Logical Tree 上导航或者查找元素,需要借助 LogicalTreeHelper 类的静态方法来实现;如果在 Visual Tree 上,需要借助 VisualTreeHelper 类的静态方法来实现。例如:我们获取一个界面上的整棵逻辑树和可视化树,具体实现如下:
// 可视化树
StringBuilder visual = new StringBuilder();
string GetVisualTree(int depth, DependencyObject obj)
{
visual.Append($"{new string(' ', depth)}{obj.GetType().Name}\n");
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
{
GetVisualTree(depth + 1, VisualTreeHelper.GetChild(obj, i));
}
return visual.ToString();
}
private void ButtonVisual_OnClick(object sender, RoutedEventArgs e)
{
MessageBox.Show(GetVisualTree(0, this), "可视化树", MessageBoxButton.OK, MessageBoxImage.Question);
}
// 逻辑树
StringBuilder logical = new StringBuilder();
string GetLogicalTree(int depth, object obj)
{
logical.Append($"{new string(' ', depth)}{obj.GetType().Name}\n");
if (!(obj is DependencyObject))
{
return logical.ToString();
}
//LogicalTreeHelper.GetChildren 获取逻辑树子对象
//obj as DependencyObject 将obj转换成 依赖对象
foreach (object child in LogicalTreeHelper.GetChildren(obj as DependencyObject))
{
GetLogicalTree(depth + 5, child);
}
return logical.ToString();
}
private void ButtonLogical_OnClick(object sender, RoutedEventArgs e)
{
MessageBox.Show(GetLogicalTree(0, this), "逻辑树", MessageBoxButton.OK, MessageBoxImage.Question);
}
获取的结果具体如下所示:

WPF 中的逻辑树(Logical Tree)与可视化元素树(Visual Tree)的更多相关文章
- WPF中的逻辑树和可视化树
WPF中的逻辑树是指XAML元素级别的嵌套关系,逻辑树中的节点对应着XAML中的元素. 为了方便地自定义控件模板,WPF在逻辑树的基础上进一步细化,形成了一个“可视化树(Visual Tree)”,树 ...
- 在WPF中减少逻辑与UI元素的耦合
原文:在WPF中减少逻辑与UI元素的耦合 在WPF中减少逻辑与UI元素的耦合 周银辉 1, 避免在逻辑中引用界面元素,别把后台数据强加给UI 一个糟糕的案例 比如说主界 ...
- 正确理解WPF中的TemplatedParent
(注:Logical Tree中文称为逻辑树,Visual Tree中文称为可视化树或者视觉树,由于名称不是很统一,文中统一用英文名称代表两个概念,况且VisualTreeHelper和Logical ...
- WPF中元素拖拽的两个实例
今天结合之前做过的一些拖拽的例子来对这个方面进行一些总结,这里主要用两个例子来说明在WPF中如何使用拖拽进行操作,元素拖拽是一个常见的操作,第一个拖拽的例子是将ListBox中的子元素拖拽到ListV ...
- UWP开发入门(十二)——神器Live Visual Tree
很久以前,我们就有Snoop这样的工具实时修改.查看正在运行的WPF程序,那时候调个样式,修改个模板,相当滋润.随着历史的车轮陷进WP的泥潭中,无论WP7的Silverlight还是WP8.1的run ...
- WPF知识点全攻略06- WPF逻辑树(Logical Tree)和可视树(Visual Tree)
介绍概念之前,先来分析一段代码: xaml代码如下: <Window x:Class="WpfApp1.MainWindow" xmlns="http://sche ...
- WPF中的Visual Tree和Logical Tree与路由事件
1.Visual Tree和Logical TreeLogical Tree:逻辑树,WPF中用户界面有一个对象树构建而成,这棵树叫做逻辑树,元素的声明分层结构形成了所谓的逻辑树!!Visual Tr ...
- 理解WPF中的视觉树和逻辑树
轉載地址:http://blog.csdn.net/changtianshuiyue/article/details/26981797 理解WPF中的视觉树和逻辑树 Understanding th ...
- WPF中Logical Tree和Visual Tree的区别
The Logical TreeThe logical tree describes the relations between elements of the user interface. The ...
随机推荐
- Java JDK8下载 (jdk-8u251-windows-x64和jdk-8u271-linux-x64.tar)
jdk-8u251-windows-x64 和 jdk-8u271-linux-x64.tar 链接:https://pan.baidu.com/s/1gci6aSIFhEhjY8F48qH39Q 提 ...
- STL_map和multimap容器
一.map/multimap的简介 map是标准的关联式容器,一个map是一个键值对序列,即(key,value)对.它提供基于key的快速检索能力. map中key值是唯一的.集合中的元素按一定的顺 ...
- 一文告诉你Java日期时间API到底有多烂
前言 你好,我是A哥(YourBatman). 好看的代码,千篇一律!难看的代码,卧槽卧槽~其实没有什么代码是"史上最烂"的,要有也只有"史上更烂". 日期是商 ...
- CACTI优化-流量接口统计total输入和输出流量数据
看图,没有优化前(没有显示流入和流出的总流量是多少): 优化后(有显示流入和流出总流量统计): 如何实现呢?本节就是处理的过程小结.第一步:登陆cacti管理平台进入控制台->模板->图形 ...
- MySQL主从配置This operation cannot be performed with a running slave io thread; run STOP SLAVE IO_THREAD FOR CHANNEL '' first.
MySQL主从配置This operation cannot be performed with a running slave io thread; run STOP SLAVE IO_THREAD ...
- Bitter.Core系列二:Bitter ORM NETCORE ORM 全网最粗暴简单易用高性能的 NETCore ORM 之数据库连接
Bitter.Core NETCore 相当的简单易用,下面附上使用示例: 数据中连接:请在你的NETCORE 项目中 创建:Bitter.json 配置文件,然后追加如下配置内容: MSSQL 连接 ...
- Oracle19c的多租户笔记
Oracle19c的多租户笔记 1.多租户的概念 PDB(PLUGGABLE DATABASE)可以理解为我们Oracle11gR2的数据库,只不过是一个实例上面可以放置多个数据库了.名称为插件式数据 ...
- 基于nginx的频率控制方案思考和实践
基于nginx的频率控制方案思考 标签: 频率控制 nginx 背景 nginx其实有自带的limit_req和limit_conn模块,不过它们需要在配置文件中进行配置才能发挥作用,每次有频控策略的 ...
- Pycharm 使用学习
作为一个菜鸟,为了督促自己坚持学习python,记录每日学习日记是一个不错的选择 电脑安装python,python可以丛网络上下载相关版本进行安装,目前我电脑安装的是pyhon 3.7.3的版本,p ...
- SQL系列总结——基础篇(一)
数据库与表.列的关系其实就像是一个Excel工作薄(workbook)与Excel表格(sheet)以及表格中的列的关系一样.关系数据库中最基本的对象有3个:表.列.用户 基本的概念名词 ...