一、什么是逻辑树

逻辑树就是描述WPF界面元素的实际构成,它是由程序在XAML中所有的UI元素组成。最显著的特点就是由布局控件、或者其他常用的控件组成。

 <Window x:Class="WpfRouteEvent.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="" Width="">
<Grid>
<StackPanel>
<TextBox></TextBox>
</StackPanel>
</Grid>
</Window>

从上面的代码中可以看出,Window、Grid、StackPanel、TextBox其实就是XAML界面的逻辑树。

二、什么是可视树

可视树是由界面上可见的元素构成的,这些元素主要是由从Visual或者Visual3D类中派生出来的类。

上面代码中的Window、Grid、StackPanel、TextBox它们本身就包含一些由Visual或者Visual3D类派生出的一些可视树的元素来组成的。

三、逻辑树和可视树的遍历

逻辑树遍历使用LogicalTreeHelper类。
可视树遍历使用VisualTreeHelper类。

演示遍历逻辑树和可视树

1、XAML界面左边显示逻辑树,右边显示可视树,代码如下:

 <Window x:Class="WpfRouteEvent.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="" Width="">
<Grid>
<DockPanel>
<Button DockPanel.Dock="Top" Click="Button_Click" Content="获取逻辑树和可视树"></Button>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<DockPanel Grid.Column="">
<TextBlock DockPanel.Dock="Top" Text="逻辑树"></TextBlock>
<TreeView Name="tvLogicTree"></TreeView>
</DockPanel>
<DockPanel Grid.Column="">
<TextBlock DockPanel.Dock="Top" Text="可视树"></TextBlock>
<TreeView Name="tvVisualTree"></TreeView>
</DockPanel>
</Grid>
</DockPanel> </Grid>
</Window>

2、添加类,用于遍历整个XAML界面的逻辑树和可视树

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media; namespace WpfRouteEvent
{
public class WpfTreeHelper
{
static string GetTypeDescription(object obj)
{
return obj.GetType().FullName;
} /// <summary>
/// 获取逻辑树
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public static TreeViewItem GetLogicTree(DependencyObject obj)
{
if (obj == null)
{
return null;
}
//创建逻辑树的节点
TreeViewItem treeItem = new TreeViewItem {Header=GetTypeDescription(obj),IsExpanded=true }; //循环遍历,获取逻辑树的所有子节点
foreach (var child in LogicalTreeHelper.GetChildren(obj))
{
//递归调用
var item = GetLogicTree(child as DependencyObject);
if (item != null)
{
treeItem.Items.Add(item);
}
} return treeItem;
} /// <summary>
/// 获取可视树
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public static TreeViewItem GetVisualTree(DependencyObject obj)
{
if (obj == null)
{
return null;
} TreeViewItem treeItem = new TreeViewItem { Header=GetTypeDescription(obj),IsExpanded=true}; for (int i = ; i < VisualTreeHelper.GetChildrenCount(obj); i++)
{
var child = VisualTreeHelper.GetChild(obj, i);
var item = GetVisualTree(child);
if (item != null)
{
treeItem.Items.Add(item);
}
} return treeItem;
}
}
}

3、在按钮的点击事件中将获取的逻辑树和可视树添加到XAML界面中

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes; namespace WpfRouteEvent
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
} private void Button_Click(object sender, RoutedEventArgs e)
{
this.tvLogicTree.Items.Add(WpfTreeHelper.GetLogicTree(this));
this.tvVisualTree.Items.Add(WpfTreeHelper.GetVisualTree(this));
}
}
}

4、点击按钮,界面运行效果

WPF路由事件一:逻辑树和可视树的更多相关文章

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

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

  2. WPF自学入门(三)WPF路由事件之内置路由事件

    有没有想过在.NET中已经有了事件机制,为什么在WPF中不直接使用.NET事件要加入路由事件来取代事件呢?最直观的原因就是典型的WPF应用程序使用很多元素关联和组合起来,是否还记得在WPF自学入门(一 ...

  3. WPF路由事件二:路由事件的三种策略

    一.什么是路由事件 路由事件是一种可以针对元素树中的多个侦听器而不是仅仅针对引发该事件的对象调用处理程序的事件.路由事件是一个CLR事件. 路由事件与一般事件的区别在于:路由事件是一种用于元素树的事件 ...

  4. WPF路由事件学习(一)

    路由事件与一般事件的区别在于:路由事件是一种用于元素树的事件,当路由事件触发后,它可以向上或向下遍历可视树和逻辑树,他用一种简单而持久的方式在每个元素上触发,而不需要任何定制的代码(如果用传统的方式实 ...

  5. WPF 路由事件 Event Routing

    原文:WPF 路由事件 Event Routing 1.路由事件介绍 之前介绍了WPF的新的依赖属性系统,本篇将介绍更高级的路由事件,替换了之前的.net普通事件.相比.net的事件,路由事件具有更强 ...

  6. WPF 自定义一个控件,当点击按钮是触发到ViewModel(业务逻辑部分)和Xaml路由事件(页面逻辑部分)

    #region - 用于绑定ViewModel部分 - public ICommand Command { get { return (ICommand)GetValue(CommandPropert ...

  7. WPF路由事件三:自定义路由事件

    与依赖项属性类似,WPF也为路由事件提供了WPF事件系统这一组成.为一个类型添加一个路由事件的方式与为类型添加依赖项属性的方法类似,添加一个自定义路由事件的步骤: 一.声明路由事件变量并注册:定义只读 ...

  8. WPF 路由事件总结

    1.什么是路由事件 已下为MSDN中的定义 功能定义:路由事件是一种可以针对元素树中的多个侦听器(而不是仅针对引发该事件的对象)调用处理程序的事件. 实现定义:路由事件是一个 CLR 事件,可以由 R ...

  9. WPF自学入门(四)WPF路由事件之自定义路由事件

    在上一遍博文中写到了内置路由事件,其实除了内置的路由事件,我们也可以进行自定义路由事件.接下来我们一起来看一下WPF中的自定义路由事件怎么进行创建吧. 创建自定义路由事件分为3个步骤: 1.声明并注册 ...

随机推荐

  1. RabbitMQ消息队列(一): Detailed Introduction 详细介绍[转]

    1. 历史 RabbitMQ是一个由erlang开发的AMQP(Advanced Message Queue )的开源实现.AMQP 的出现其实也是应了广大人民群众的需求,虽然在同步消息通讯的世界里有 ...

  2. 利用HttpWebRequest模拟表单提交 JQuery 的一个轻量级 Guid 字符串拓展插件. 轻量级Config文件AppSettings节点编辑帮助类

    利用HttpWebRequest模拟表单提交   1 using System; 2 using System.Collections.Specialized; 3 using System.IO; ...

  3. PO_本地一揽子采购协议(流程)

    2014-06-04 Created By BaoXinjian

  4. Python直接赋值、浅拷贝和深度拷贝解析

    直接赋值:其实就是对象的引用(别名). 浅拷贝(copy):拷贝父对象,不会拷贝对象的内部的子对象. 深拷贝(deepcopy): copy 模块的 deepcopy 方法,完全拷贝了父对象及其子对象 ...

  5. Math.Celing、Math.Floor、Math.DivRem与Math.BigMul

    返回大于或等于指定数字的最小整数.例如: double a=Math.Celing(0.00);  //0 double a=Math.Celing(0.40);  //1 double a=Math ...

  6. C# POST与参数的字符串格式

    参数拼接方法:&  类似url参数.然后转化为字节型 string postdate = "Submit=" + Submit + "&dopost=&q ...

  7. Spring Boot(一):初步认识

    简介 Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置 ...

  8. 深入理解Docker Volume(二)

      一开始,认为Volume是用来持久化的,但是这实际上不对,因为认为Volume是用来持久化的同学一定是认为容器无法持久化,所以有了Volume来帮助容器持久化,事实上,容器会一直存在,除非你删除他 ...

  9. U3D正播反播动画剪辑

    正播就是直接play item.animation.Play("a"); 反播: item.animation.Play("a"); item.animatio ...

  10. UrlOper

    using System; using System.Text.RegularExpressions; using System.Web; using System.Collections.Speci ...