• WPF 中的逻辑树(Logical Tree)与可视化元素树(Visual Tree)


    一、前言

    ​ WPF 中有两种“树”:逻辑树(Logical Tree)可视化元素树(Visual Tree)。 Logical Tree 最显著的特点就是它完全由布局组件和控件组成。那么 Visual Tree 是什么呢?

    ​ 如果我们仔细观察一棵树的树叶,会发现树叶的脉络也像一棵“树”——有自己的基部并向上生长出多级分叉。在 WPF 的 Logical Tree 上,充当“树叶”的一般都是控件,如果我们仔细观察控件,会发现 WPF 控件本身也是一颗由更细微级别的组件(它们不是控件,而是一些可视化组件,派生自 Visual 类)组成的“树”。即当我们把 Logical Tree 延伸至控件的模板(Template)组件级别时,我们得到的就是 Visual Tree。

    ​ 实际工作中,大多数情况下我们都是在与 Lgical Tree 打交道,如果你的程序需要借助 Visual Tree 来完成一些与业务逻辑(而不是纯表现逻辑)相关的功能,多半是程序设计不良造成的,最好重新考虑逻辑、功能和数据类型方面的设计。

    二、两棵“树”的操作

    如果在 Logical Tree 上导航或者查找元素,需要借助 LogicalTreeHelper 类的静态方法来实现;如果在 Visual Tree 上,需要借助 VisualTreeHelper 类的静态方法来实现。例如:我们获取一个界面上的整棵逻辑树和可视化树,具体实现如下:

    // 可视化树
            StringBuilder visual = new StringBuilder();
            string GetVisualTree(int depth, DependencyObject obj)
            {
                visual.Append($"{new string(' ', depth)}{obj.GetType().Name}
    ");
    
                for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
                {
                    GetVisualTree(depth + 1, VisualTreeHelper.GetChild(obj, i));
                }
                return visual.ToString();
            }
            private void ButtonVisual_OnClick(object sender, RoutedEventArgs e)
            {
                MessageBox.Show(GetVisualTree(0, this), "可视化树", MessageBoxButton.OK, MessageBoxImage.Question);
            }
    
    
            // 逻辑树
            StringBuilder logical = new StringBuilder();
            string GetLogicalTree(int depth, object obj)
            {
                logical.Append($"{new string(' ', depth)}{obj.GetType().Name}
    ");
                if (!(obj is DependencyObject))
                {
                   return logical.ToString();
                }
    
                //LogicalTreeHelper.GetChildren 获取逻辑树子对象   
                //obj as DependencyObject  将obj转换成 依赖对象  
                foreach (object child in LogicalTreeHelper.GetChildren(obj as DependencyObject))
                {
                    GetLogicalTree(depth + 5, child);
                }
    
                return logical.ToString();
            }
    
            private void ButtonLogical_OnClick(object sender, RoutedEventArgs e)
            {
                MessageBox.Show(GetLogicalTree(0, this), "逻辑树", MessageBoxButton.OK, MessageBoxImage.Question);
            }
    

    ​ 获取的结果具体如下所示:

  • 相关阅读:
    linux下的watch命令
    Erlang运行时的错误
    Redis查看帮助文档
    PO Box简介
    用erlang写的kmp算法
    laravel全过程
    artdialog 弹出框
    支持触屏版的旋转幻灯片
    android生成APP的名字,图标,开机动画
    使用Eclipse构建app网站应用
  • 原文地址:https://www.cnblogs.com/dongweian/p/14382022.html
Copyright © 2020-2023  润新知