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


    一、什么是逻辑树

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

     1 <Window x:Class="WpfRouteEvent.MainWindow"
     2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     4         Title="MainWindow" Height="350" Width="525">
     5     <Grid>
     6         <StackPanel>
     7             <TextBox></TextBox>
     8         </StackPanel>
     9     </Grid>
    10 </Window>

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

    二、什么是可视树

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

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

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

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

    演示遍历逻辑树和可视树

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

     1 <Window x:Class="WpfRouteEvent.MainWindow"
     2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     4         Title="MainWindow" Height="350" Width="525">
     5     <Grid>
     6         <DockPanel>
     7             <Button DockPanel.Dock="Top" Click="Button_Click" Content="获取逻辑树和可视树"></Button>
     8             <Grid>
     9                 <Grid.ColumnDefinitions>
    10                     <ColumnDefinition></ColumnDefinition>
    11                     <ColumnDefinition></ColumnDefinition>
    12                 </Grid.ColumnDefinitions>
    13                 <DockPanel Grid.Column="0">
    14                     <TextBlock DockPanel.Dock="Top" Text="逻辑树"></TextBlock>
    15                     <TreeView Name="tvLogicTree"></TreeView>
    16                 </DockPanel>
    17                 <DockPanel Grid.Column="1">
    18                     <TextBlock DockPanel.Dock="Top" Text="可视树"></TextBlock>
    19                     <TreeView Name="tvVisualTree"></TreeView>
    20                 </DockPanel>
    21             </Grid>
    22         </DockPanel>
    23         
    24     </Grid>
    25 </Window>

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

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading.Tasks;
     6 using System.Windows;
     7 using System.Windows.Controls;
     8 using System.Windows.Media;
     9 
    10 namespace WpfRouteEvent
    11 {
    12     public class WpfTreeHelper
    13     {
    14         static string GetTypeDescription(object obj)
    15         {
    16             return obj.GetType().FullName;
    17         }
    18 
    19         /// <summary>
    20         /// 获取逻辑树
    21         /// </summary>
    22         /// <param name="obj"></param>
    23         /// <returns></returns>
    24         public static TreeViewItem GetLogicTree(DependencyObject obj)
    25         {
    26             if (obj == null)
    27             {
    28                 return null;
    29             }
    30             //创建逻辑树的节点
    31             TreeViewItem treeItem = new TreeViewItem {Header=GetTypeDescription(obj),IsExpanded=true };
    32 
    33             //循环遍历,获取逻辑树的所有子节点
    34             foreach (var child in LogicalTreeHelper.GetChildren(obj))
    35             {
    36                 //递归调用
    37                 var item = GetLogicTree(child as DependencyObject);
    38                 if (item != null)
    39                 {
    40                     treeItem.Items.Add(item);
    41                 }
    42             }
    43 
    44             return treeItem;
    45         }
    46 
    47         /// <summary>
    48         /// 获取可视树
    49         /// </summary>
    50         /// <param name="obj"></param>
    51         /// <returns></returns>
    52         public static TreeViewItem GetVisualTree(DependencyObject obj)
    53         {
    54             if (obj == null)
    55             {
    56                 return null;
    57             }
    58 
    59             TreeViewItem treeItem = new TreeViewItem { Header=GetTypeDescription(obj),IsExpanded=true};
    60 
    61             for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
    62             {
    63                 var child = VisualTreeHelper.GetChild(obj, i);
    64                 var item = GetVisualTree(child);
    65                 if (item != null)
    66                 {
    67                     treeItem.Items.Add(item);
    68                 }
    69             }
    70 
    71             return treeItem;
    72         }
    73     }
    74 }

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

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading.Tasks;
     6 using System.Windows;
     7 using System.Windows.Controls;
     8 using System.Windows.Data;
     9 using System.Windows.Documents;
    10 using System.Windows.Input;
    11 using System.Windows.Media;
    12 using System.Windows.Media.Imaging;
    13 using System.Windows.Navigation;
    14 using System.Windows.Shapes;
    15 
    16 namespace WpfRouteEvent
    17 {
    18     /// <summary>
    19     /// MainWindow.xaml 的交互逻辑
    20     /// </summary>
    21     public partial class MainWindow : Window
    22     {
    23         public MainWindow()
    24         {
    25             InitializeComponent();
    26         }
    27 
    28         private void Button_Click(object sender, RoutedEventArgs e)
    29         {
    30             this.tvLogicTree.Items.Add(WpfTreeHelper.GetLogicTree(this));
    31             this.tvVisualTree.Items.Add(WpfTreeHelper.GetVisualTree(this));
    32         }
    33     }
    34 }

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

  • 相关阅读:
    ActionBar 值 addTab 的小提示
    Android Studio Gradle project refresh failed No such property classpath for class
    Android Studio 初始新建项目时 build gradle project 超级慢的原因
    ActionBar之style出现Cannot resolve symbol 'Theme' 错误
    Android之ActionBar、Tabs、Fragment、ViewPager实现标签页切换并缓存页面
    Linux使用rsync客户端与服务端同步目录进行备份
    Linux服务器导入导出SVN项目
    CentOS6.3配置SVN之subversion1.7.7
    Linux增加swap分区大小
    CentOS6.2编译gcc失败,kernel-headers错误
  • 原文地址:https://www.cnblogs.com/dotnet261010/p/6367924.html
Copyright © 2020-2023  润新知