【WPF】逻辑树和视觉树

     WPF中提供了遍历逻辑树和视觉树的辅助类:System.Windows.LogicalTreeHelper和 System.Windows.Media.VisualTreeHelper。 注意遍历的位置,逻辑树可以在类的构造函数中遍历。但是,视觉树必须在经过至少一次的布局后才能形成。 所以它不能在构造函数遍历。通常是在OnContentRendered进行,这个函数为在布局发生后被调用。 其实每个Tree结点元素本身也包含了遍历的方法。 比如,Visual类包含了三个保护成员方法VisualParent、 VisualChildrenCount、GetVisualChild。通过它们可以访问Visual的父元素和子元素。而对于 FrameworkElement,它通常定义了一个公共的Parent属性表示其逻辑父元素。 特定的FrameworkElement子类用不同的方式暴露了它的逻辑子元素。比如部分子元素是Children Collection,有是有时Content属性,Content属性强制元素只能有一个逻辑子元素。

     为了方便理解,直接上代码:

     前台XAML代码如下:

<Window x:Class="WpfApp1112.Window2"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window2" Height="300" Width="300">
    <StackPanel>
        <Label>Hello,world!</Label>
    </StackPanel>
</Window>

     后台代码如下:

    /// <summary>
    /// Window2.xaml 的交互逻辑
    /// </summary>
    public partial class Window2 : Window
    {
        public Window2()
        {
            InitializeComponent();
            printLogincalTree(0, this);
        }
        protected override void OnContentRendered(EventArgs e)
        {
            base.OnContentRendered(e);
            printVisualTree(0,this);
        }

        /// <summary>
        /// 打印逻辑树
        /// </summary>
        /// <param name="depth"></param>
        /// <param name="obj"></param>
        void printLogincalTree(int depth, object obj)
        {
            Debug.WriteLine(new string(' ', depth) + obj); //打印空格,方便查看

            if (!(obj is DependencyObject)) return;        //如果不是DependencyObject,如string等类型

            //递归打印逻辑树
            foreach (object child in LogicalTreeHelper.GetChildren(obj as DependencyObject))
            {
                printLogincalTree(depth + 1, child);
            }
        }

        /// <summary>
        /// 打印视觉树
        /// </summary>
        /// <param name="depth"></param>
        /// <param name="obj"></param>
        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));
            }
        }
    }

打印结果如下:

 

posted @ 2013-11-20 10:34  `一群小猪.  阅读(1508)  评论(0编辑  收藏  举报