XAML天生就是用来呈现用户界面的,这是由于它具有层次化的特性。在WPF中,用户界面由一个对象树构建而成,这棵树叫作逻辑树。逻辑树的概念很直观,但是为什么要关注它呢?因为几乎WPF的每一方面(属性、事件、资源等)都有与逻辑树相关联的行为。例如,属性值有时会沿着树自动传递给子元素,而触发的事件可以自底向上或自顶向下遍历树。

与逻辑树类似的一个概念是可视树。可视树基本上是逻辑树的扩展,在可视树中,节点都被打散,分放到核心可视组件中。可视树提供了一些详细的可视化实现,而不是把每个元素当作一个“黑盒”。例如,虽然ListBox从逻辑上讲是一个单独的控件,但它的默认可视呈现是由更多的原始WPF 元素组成的:一个Border对象、两个ScrollBar及其他一些元素。并非所有的逻辑树节点都会出现在可视树中,只有从System.Windows.Media.Visual或System.Windows.Media.Visual3D派生的元素才会被包含进去。其他元素(和一些简单的字符串内容,如代码清单3-1中的内容)不会包含在内,因为它们自己并没有与生俱来的呈现行为。

逻辑树是静态的,不会受到程序员的干扰(例如动态添加/删除元素),但只要用户切换不同的Windows主题,可视树就会改变。

使用System.Windows.LogicalTreeHelper和System.Windows.Media.VisualTreeHelper这两个有些对称的类可以方便地遍历逻辑树和可视树,下边提供两个方法以此遍历wpf中的可视树与逻辑树:

  1. private void PrintVisualTree(int depth, DependencyObject obj)
  2. {
  3. Console.WriteLine(depth + " " + obj);
  4. for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
  5. PrintVisualTree(depth + 1, VisualTreeHelper.GetChild(obj, i));
  6. }
  1. private void PrintLogicTree(int depth, object obj)
  2. {
  3. Console.WriteLine(depth + " " + obj);
  4. if (!(obj is DependencyObject))
  5. return;
  6. foreach (object child in LogicalTreeHelper.GetChildren(obj as DependencyObject))
  7. PrintLogicTree(depth + 1, child);
  8. }

虽然在Window的构造函数中就可以遍历逻辑树,但可视树直到Window完成至少一次布局之后才会有节点,否则是空的。所以遍历可视树需要在控件渲染完再进行遍历,可以在OnContentRendered中进行调用:

  1. protected override void OnContentRendered(EventArgs e)
  2. {
  3. base.OnContentRendered(e);
  4. PrintVisualTree(0, this);
  5. }

wpf 逻辑树与可视化树的更多相关文章

  1. 【WPF学习】第五十八章 理解逻辑树和可视化树

    在前面章节中,花费大量时间分析了窗口的内容模型——换句话说,研究了如何在其他元素中嵌套元素,进而构建完整的窗口. 例如,考虑下图中显示的一个非常简单的窗口,该窗口包含两个按钮.为创建该按钮,在窗口中嵌 ...

  2. WPF中的逻辑树和可视化树

    WPF中的逻辑树是指XAML元素级别的嵌套关系,逻辑树中的节点对应着XAML中的元素. 为了方便地自定义控件模板,WPF在逻辑树的基础上进一步细化,形成了一个“可视化树(Visual Tree)”,树 ...

  3. WPF学习(4)逻辑树和可视树

    前面几节说了一些WPF的基础,包括XAML和布局等.在接下来的几节,我们来说说WPF的核心概念,包括逻辑树和可视树.依赖对象和依赖属性.路由事件.命令这几个部分.本节介绍下逻辑树(Logical Tr ...

  4. C# WPF 父控件通过使用可视化树找到子控件

    在我们使用WPF设计前台界面时,经常会重写数据模板,或者把控件放到数据模板里.但是一旦将控件放到数据模板中,在后台就没有办法通过控件的名字来获取它了,更没办法对它进行操作(例如,隐藏,改变控件的某个值 ...

  5. WPF路由事件一:逻辑树和可视树

    一.什么是逻辑树 逻辑树就是描述WPF界面元素的实际构成,它是由程序在XAML中所有的UI元素组成.最显著的特点就是由布局控件.或者其他常用的控件组成. <Window x:Class=&quo ...

  6. wpf 可视化树的注意点

    将控件的visibility 设置为collapse时,控件的可视化树并未生成,此时并不能查找到控件内的子控件. 若某控件想对用户不可见,且可以生成可视化树,则需将控件的visibility 设置为h ...

  7. WPF 可视化树的用途

    1.可视化树的主要用途: 1.可以使用样式改变可视化树中的一个元素.可以使用Style.TargetType属性选择希望修改 的特定元素.甚至当控件属性发生变化时,可以使用触发器自动完成更改. 2.可 ...

  8. 【Win10 应用开发】使用“实时可视化树”工具查看应用界面元素

    记得有朋友问老周,系统中的“计算器”应用的界面菜单是怎么做的.其实,你可以用VS 2015的新工具来查看它的界面结构. 实时可视化树工具只能查看XAML定义的界面,如WPF和Win App.现在,Wi ...

  9. AI逻辑实现-取舍行为树还是状态机

    AI逻辑实现-选择行为树还是状态机? 关注AI的朋友可能会看过赖勇浩翻译的<有限状态机时代终结的10大理由> ,里面谈到了状态机的诸多弊端.同时在ppt(附上下载地址)中述说了行为树的诸多 ...

随机推荐

  1. jsonp是什么【转载自JavaScript微信公众号】

    转自 http://mp.weixin.qq.com/s/xNnKAeLv6sO0T-IvP2AUlQ          JavaScript微信公众号 一.JSONP的诞生 首先,因为ajax无法跨 ...

  2. 安天移动安全应对“DressCode”威胁,发布企业移动威胁检查工具

    近日,一种名为"DressCode"的恶意代码引起了国内安全行业的关注,该恶意代码以企业员工的移动设备作为跳板对企业内网进行攻击,对企业安全造成严重威胁.安天移动安全公司威胁情报团 ...

  3. Visual Studio高级调试技巧

    1. 设置软件断点,运行到目标位置启动调试器 方法①:使用汇编指令(注:x64 c++不支持嵌入汇编) _asm 方法②:编译器提供的方法 __debugbreak(); 方法③:使用windows ...

  4. Jquery便利对象

    xhr=[object object]    $.each(xhr, function (key, val) {                     alert(key + '=' + val); ...

  5. 工作中常用的awk命令

    http://man.linuxde.net/awk 1.为一列id加逗号 awk 'BEGIN {ORS=","}{print $1}' test.txt 2.统计一列id中重复 ...

  6. Domino----The Address Book does not contain a cross certificate capable of validating the public key.

    The Address Book does not contain a cross certificate capable of validating the public key. 地址本不包含交叉 ...

  7. mybatis Caused by: org.apache.ibatis.reflection.ReflectionException: Error instantiating class .. with invalid types () or values (). Cause: java.lang.NoSuchMethodException: ...<init>()

    如果有带参数的构造器,编译器不会自动生成无参构造器.当查询需要返回对象时,ORM框架用反射来调用对象的无参构造函数,所以会导致此类异常 public Test(){ }

  8. FragmentActivity_左右滑动的碎片

    test1.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:an ...

  9. IDA的脚本IDC的一个简单使用

    目的:主要是想学习一下IDA的IDC的脚本的使用.这里做了一个小的测试. 这里使用的是VS2015Community来生成文件的. 一.编写测试程序: 这里先生成我们的目标数据. 然后编写测试程序.得 ...

  10. 禁用ViewPager边界滑动效果(转)

    反射设置方法 private EdgeEffectCompat leftEdge; private EdgeEffectCompat rightEdge; public void DisableLRS ...