WPF学习系列017: 3.1 逻辑树与可视树

 

  •  
    1. 用户界面由一个对象树构建而成,这棵树叫作逻辑树。注意,即使是WPF用户界面的逻辑树也并不是用XAML创建,通过过程式代码同样可以实现。
    1. 逻辑树之所以重要,是因为几乎WPF的每一方面(属性、事件、资源等)都有与逻辑树相关联的行为。
    1. 可视树是逻辑树的扩展。可视树将逻辑树的节点打散,分放到核心可视组件中。它表述了一些详细的可视化实现,而不是把每个元素当做一个“黑盒”。
    2. 并非左右的逻辑树节点都会出现在可视树中,只有从System.Windows.Media.VisualSystem.Windows.Media.Visual3D派生的元素才会被包含进去。
    3. 通过 XamlPad 的工具可以呈现出 XAML 的可视树(和属性值)。当 XAML 放入一个 Window 对象时,无法看到它的可视树,但只要将该 Window 元素改为 Page 元素(并删除 SizeToContent 属性)就可以看到了。
    1. 可视树是WPF架构的核心组成部分,通常不用去管它们,除非要对控件进行完全的重塑或者做一些底层绘制。
    2. 可以使用 System.Windows.LogicalTreeHelper System.Windows.Media.VisualTreeHelper 这两个类方便地遍历逻辑树和可视树。
    1. Debug.WriteLine 函数输出的内容在 Visual Studio 的“输出”窗口可以看到
    2. 可视树直到Window完成至少一次布局之后才会有节点,因此在OnContentRendered中调用,因为OnContentRendered是在布局完成之后才被调用的。
    1. 不要根据具体的可视树写代码。因为逻辑树是静态的,不会受到程序员的干扰,但可视树随时会发生变化。
    2. 部分元素有自己的实例方法,在两种树中进行操作。例如Visual类包含3protected的成员(VisualParentVisualChildrenCountGetVisualChild)用于验证它的可视父节点和孩子节点。FrameworkElementParent属性,用于呈现逻辑父节点。某些FrameworkElement的子类会以不同的方式提供它们的逻辑子元素。
    3. 可视树通常会被简化为元素树,因为它们既包含了逻辑树中的元素,也包含了可视树中的某些元素。术语“可视树”是用来描述任何一棵包含可是元素的字数。
  • 3.1 逻辑树与可视树

    例如:以 XAML 形式表示的一个简单的 About 对话框

    <Window x:Class="AboutDialogProgram.AboutDialog"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    Title="About WPF Unleashed"

    SizeToContent="WidthAndHeight"

    Background="OrangeRed">

    <StackPanel>

    <Label FontWeight="Bold"

    FontSize="20"

    Foreground="White">

    WPF Unleashed (Version 3.0)

    </Label>

    <Label>

    © 2006 SAMS Publishing

    </Label>

    <Label>

    Installed Chapters:

    </Label>

    <ListBox>

    <ListBoxItem>

    Chapter 1

    </ListBoxItem>

    <ListBoxItem>

    Chapter 2

    </ListBoxItem>

    </ListBox>

    <StackPanel Orientation="Horizontal"

    HorizontalAlignment="Center">

    <Button MinWidth="75"

    Margin="10">

    Help

    </Button>

    <Button MinWidth="75"

    Margin="10">

    OK

    </Button>

    </StackPanel>

    <StatusBar>

    You have successfully registered this product.

    </StatusBar>

    </StackPanel>

    </Window>

    例如:属性值有时会沿着树自动传递给子元素;触发的事件可以自底向上或自顶向下遍历树。

    XamlPad 工具下载地址:

    http://blogs.msdn.com/b/llobo/archive/2008/08/25/xamlpadx-4-0.aspx

    例如:遍历和打印逻辑树和可视树

    using System;

    using System.Windows;

    using System.Windows.Media;

    using System.Diagnostics;

     

    namespace AboutDialogProgram

    {

        /// <summary>

        /// MainWindow.xaml 的交互逻辑

        /// </summary>

        public partial class AboutDialog : Window

        {

            public AboutDialog()

            {

                InitializeComponent();

                PrintLogicalTree(0, this);

            }

     

            protected override void OnContentRendered(EventArgs e)

            {

                base.OnContentRendered(e);

                PrintVisualTree(0, this);

            }

     

            void PrintLogicalTree(int depth, object obj)

            {

                // 打印对象,使用前置空格表示深度

                Debug.WriteLine(new string(' ', depth) + obj);

     

                // 有时,叶子节点不是 DependencyObject,如 string

                if (!(obj is DependencyObject)) return;

     

                // 递归调用每个逻辑子节点

                foreach (Object child in LogicalTreeHelper.GetChildren(obj as DependencyObject))

                {

                    PrintLogicalTree(depth + 1, child);

                }

            }

     

            void PrintVisualTree(int depth, DependencyObject obj)

            {

                // 打印对象,使用前置空格表示深度

                Debug.WriteLine(new string(' ', depth) + obj);

     

                // 递归调用每个可视子节点

                for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)

                {

                    PrintVisualTree(depth + 1, VisualTreeHelper.GetChild(obj, i));

                }

            }

        }

    }

    注意:

     

     

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值