WPF路由事件一:逻辑树和可视树
一、什么是逻辑树
逻辑树就是描述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路由事件一:逻辑树和可视树的更多相关文章
- WPF学习(4)逻辑树和可视树
前面几节说了一些WPF的基础,包括XAML和布局等.在接下来的几节,我们来说说WPF的核心概念,包括逻辑树和可视树.依赖对象和依赖属性.路由事件.命令这几个部分.本节介绍下逻辑树(Logical Tr ...
- WPF自学入门(三)WPF路由事件之内置路由事件
有没有想过在.NET中已经有了事件机制,为什么在WPF中不直接使用.NET事件要加入路由事件来取代事件呢?最直观的原因就是典型的WPF应用程序使用很多元素关联和组合起来,是否还记得在WPF自学入门(一 ...
- WPF路由事件二:路由事件的三种策略
一.什么是路由事件 路由事件是一种可以针对元素树中的多个侦听器而不是仅仅针对引发该事件的对象调用处理程序的事件.路由事件是一个CLR事件. 路由事件与一般事件的区别在于:路由事件是一种用于元素树的事件 ...
- WPF路由事件学习(一)
路由事件与一般事件的区别在于:路由事件是一种用于元素树的事件,当路由事件触发后,它可以向上或向下遍历可视树和逻辑树,他用一种简单而持久的方式在每个元素上触发,而不需要任何定制的代码(如果用传统的方式实 ...
- WPF 路由事件 Event Routing
原文:WPF 路由事件 Event Routing 1.路由事件介绍 之前介绍了WPF的新的依赖属性系统,本篇将介绍更高级的路由事件,替换了之前的.net普通事件.相比.net的事件,路由事件具有更强 ...
- WPF 自定义一个控件,当点击按钮是触发到ViewModel(业务逻辑部分)和Xaml路由事件(页面逻辑部分)
#region - 用于绑定ViewModel部分 - public ICommand Command { get { return (ICommand)GetValue(CommandPropert ...
- WPF路由事件三:自定义路由事件
与依赖项属性类似,WPF也为路由事件提供了WPF事件系统这一组成.为一个类型添加一个路由事件的方式与为类型添加依赖项属性的方法类似,添加一个自定义路由事件的步骤: 一.声明路由事件变量并注册:定义只读 ...
- WPF 路由事件总结
1.什么是路由事件 已下为MSDN中的定义 功能定义:路由事件是一种可以针对元素树中的多个侦听器(而不是仅针对引发该事件的对象)调用处理程序的事件. 实现定义:路由事件是一个 CLR 事件,可以由 R ...
- WPF自学入门(四)WPF路由事件之自定义路由事件
在上一遍博文中写到了内置路由事件,其实除了内置的路由事件,我们也可以进行自定义路由事件.接下来我们一起来看一下WPF中的自定义路由事件怎么进行创建吧. 创建自定义路由事件分为3个步骤: 1.声明并注册 ...
随机推荐
- hadoop集群虚拟机配置
hadoop_1, hadoop_2, hadoop_3 用户名riluo 密码19841984 查看Linux自带的JDK是否已安装 (卸载centOS已安装的1.4) 安装好的CentOS会自带O ...
- SecureCRT 设置中文编码
http://www.diybl.com/course/6_system/linux/Linuxjs/20090326/163546.html 装了个secureCRT,可老是出现乱码 于是 ...
- su: user tomcat does not exist
http://www.cnblogs.com/allegro/p/5005352.html 问题在于 你的startup.sh 里面设置了 用户,你需要修改为root或者tomcat用户 这是开发 迁 ...
- ASP.NET MVC下的异步Action的定义和执行原理[转]
http://www.cnblogs.com/artech/archive/2012/06/20/async-action-in-mvc.html Visual Studio提供的Controller ...
- CListCtrl控件中显示进度条
CListCtrl控件的subitem中显示进度条 http://www.codeproject.com/Articles/6813/List-Control-Extended-for-Progres ...
- Python min() 函数
描述 min() 方法返回给定参数的最小值,参数可以为序列. 语法 以下是 min() 方法的语法: min( x, y, z, .... ) 参数 x -- 数值表达式. y -- 数值表达式. z ...
- js 与 php 时间戳的区别(毫秒与秒的计算方式)
js是以毫秒为单位计算的,php是以秒为单位计算的,所以转换时记得*/1000 //距离时间的时间戳 var suoshengshijian = <?php echo $expire_time_ ...
- unity5 Text
unity5中,添加Text对象: 在其它对象的脚本中如果想引用此Text,则应定义: public UnityEngine.UI.Text myText; 然后把对象拖到变量上即可. 注: 1,需要 ...
- CentOS安装Webmin
解析:Webmin是目前功能最强大的基于Web的Unix系统管理工具.管理员通过浏览器访问Webmin的各种管理功能并完成相应的管理动作.目前 Webmin支持绝大多数的Unix系统,这些系统除了各种 ...
- WCF入门学习3-配置文件与部署iis
配置文件设置 --------------------------------------------------- 创建的时候都会有个配置文件,其实有一个WCF配置编辑器,右键就可以点出来设置. 需 ...