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

2022-04-17 05:50:05

一、什么是逻辑树

逻辑树就是描述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>QiNeFT            <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路由事件之逻辑树和可视树遍历

到此这篇关于WPF路由事件之逻辑树和可视树遍历的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持我们。