WPF路由事件之逻辑树和可视树遍历

 更新时间:2022年02月25日 14:46:20   作者:.NET开发菜鸟  
本文详细讲解了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="350" Width="525">
    <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="350" Width="525">
    <Grid>
        <DockPanel>
            <Button DockPanel.Dock="Top" Click="Button_Click" Content="获取逻辑树和可视树"></Button>
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition></ColumnDefinition>
                    <ColumnDefinition></ColumnDefinition>
                </Grid.ColumnDefinitions>
                <DockPanel Grid.Column="0">
                    <TextBlock DockPanel.Dock="Top" Text="逻辑树"></TextBlock>
                    <TreeView Name="tvLogicTree"></TreeView>
                </DockPanel>
                <DockPanel Grid.Column="1">
                    <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 = 0; 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路由事件之逻辑树和可视树遍历的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • .net core异常中间件的使用

    .net core异常中间件的使用

    本文主要简单介绍一下异常中间件的使用,学习.net core的同学可以了解下本文
    2021-06-06
  • 在.net项目使用JSONSchema示例详解

    在.net项目使用JSONSchema示例详解

    这篇文章主要为大家介绍了在.net项目使用JSONSchema的示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-05-05
  • asp.net core配置文件加载过程的深入了解

    asp.net core配置文件加载过程的深入了解

    这篇文章主要给大家介绍了关于asp.net core配置文件加载过程的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2018-12-12
  • repeater 分列显示以及布局的实例代码

    repeater 分列显示以及布局的实例代码

    repeater 分列显示以及布局的实例代码,需要的朋友可以参考一下
    2013-03-03
  • ASP.net的验证控件浅析

    ASP.net的验证控件浅析

    前些天在做注册页面的验证的时候,用了下ASP.net的验证控件,有一些体会,特写下这篇博客,如果有朋友有不同ideas,欢迎大家留言
    2011-11-11
  • asp.net ubb使用代码

    asp.net ubb使用代码

    asp.net ubb使用代码,以前脚本之家曾经发过一篇稍有区别的代码,大家一起参考下吧。
    2009-12-12
  • VB.NET生成随机串或随机数字的方法总结

    VB.NET生成随机串或随机数字的方法总结

    本篇文章主要介绍了VB.NET生成随机串或随机数字的方法,具有一定的参考价值,有需要的可以了解一下。
    2016-11-11
  • .NET实现工资管理系统

    .NET实现工资管理系统

    这篇文章主要为大家详细介绍了.NET实现工资管理系统,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-01-01
  • .NET垃圾回收器原理及使用

    .NET垃圾回收器原理及使用

    这篇文章介绍了.NET垃圾回收器原理及使用方法,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-01-01
  • asp.net Forms身份验证和基于角色的权限访问

    asp.net Forms身份验证和基于角色的权限访问

    Forms身份验证用来判断是否合法用户,当用户合法后,再通过用户的角色决定能访问的页面。
    2009-09-09

最新评论