Silverlight中只有可视化树,没有WPF中的逻辑树,这一点可从SL的sdk文档中得到印证:

可视化树概念也存在于 WPF 中,它与 Silverlight 的可视化树概念类似。然而,一个显著的差异是 WPF 还提供一个附加的筛选器或对象树(称为"逻辑树")的概念。逻辑树概念与某些属性系统行为相关。Silverlight 不通过帮助器类来公开此逻辑树。Silverlight 中的确存在某些(但并非所有)相关的属性行为,但由于没有用于访问这些行为的帮助器 API,因此,逻辑树概念在 Silverlight 中将没有用武之地,因此本文档不讨论它。缺少逻辑树而引发的一个很小的兼容性问题是:FrameworkElement..::..Parent 属性行为在 Silverlight 版本 3 中是不同的,它实际上报告可视化树父项。

利用XamlPad,可以查看简单xaml(指不加载第三方程序集的xaml)的对象树:

xamlpad程序安装silverlight的sdk后,默认安装于x:\Program Files\Microsoft SDKs\Windows\v6.0A\Bin\下

如下图:


从上图可以看到,一个普通的Button控件,在可视化(对象)树里表现为:ButtomChrome,ContentPresenter,TextBlock的组合

另外Silverlight中提供了一个VisualTreeHelper工具类,用于操作可视化树,里面有4个静态方法:

官方解释如下:

FindElementsInHostCoordinates  检索一组对象,这些对象位于某一对象的坐标空间的指定点或 Rect 内。
 GetChild 使用提供的索引,通过检查可视化树获取所提供对象的特定子对象。
 GetChildrenCount 返回在可视化树中在某一对象的子集合中存在的子级的数目。
 GetParent 返回可视化树中某一对象的父对象。

通俗点说:FindElementsInHostCoordinates常用于对象的碰撞检测,GetChild用于获取下级子对象(注意仅仅是下级,而非所有子对象,如果要获取所有子对象,需要自己写代码遍历),GetChildrenCount用于获取下级子对象的个数,GetParent用于获取某对象的上级子对象

测试代码:

代码

<UserControl x:Class="ToolsTest.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480">
  <Grid x:Name="LayoutRoot">      
        <StackPanel x:Name="sp" HorizontalAlignment="Left">
            <TextBlock Text="Test TextBlock" Height="25" Width="100" x:Name="txt"></TextBlock>
            <Button x:Name="btn1" Content="button1" Height="25" Width="100" ></Button>
            <StackPanel x:Name="sp2">
                <Button x:Name="btn2" Content="button2" Height="25" Width="100" ></Button>
            </StackPanel>
            <Button x:Name="btn3" Content="button3"></Button>
        </StackPanel>
        <Button x:Name="btnClick" Content="Test" Height="22" Width="80" HorizontalAlignment="Center" VerticalAlignment="Bottom" Click="btnClick_Click" ></Button>
  </Grid>
</UserControl>

代码

using System.Linq;
using System.Windows;
using System.Collections.Generic;
using System.Windows.Controls;
using System.Windows.Media;

namespace ToolsTest
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
        }

private void btnClick_Click(object sender, RoutedEventArgs e)
        {
            int _childCount = VisualTreeHelper.GetChildrenCount(this);
            MessageBox.Show("MainPage下级子对象总数:" + _childCount.ToString());//就是一个Grid,所以返回1

IEnumerable<Button> AllButtons = FindChildren<Button>(this);//得到所有的Buttons

int i =0;
            foreach (Button btn in AllButtons)
            {
                i++;
                MessageBox.Show(string.Format("第{0}个按钮[{1}]的内容为:{2}",i,btn.Name,btn.Content));                
            }

StackPanel sp = VisualTreeHelper.GetParent(btn2) as StackPanel;
            MessageBox.Show(string.Format("{0}的上级对象是{1}",btn2.Content,sp.Name));

Rect rect = new Rect(0, 0, 100, 25);

IEnumerable<UIElement> check = VisualTreeHelper.FindElementsInHostCoordinates(rect, this); //检测MainPage的0,0到100,25矩形区域内有哪些元素

foreach (UIElement item in check)
            {
                string _name = item.GetValue(NameProperty).ToString();
                if (_name.Length > 0)
                {
                    MessageBox.Show(_name);
                }
            }           
        }

/// <summary>
        /// 来自博客园"木野狐"的特定类型子对象方法
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="parent"></param>
        /// <returns></returns>
        public IEnumerable<T> FindChildren<T>(DependencyObject parent) where T : class
        {
            var count = VisualTreeHelper.GetChildrenCount(parent);
            if (count > 0)
            {
                for (var i = 0; i < count; i++)
                {
                    var child = VisualTreeHelper.GetChild(parent, i);
                    var t = child as T;
                    if (t != null)
                        yield return t;

var children = FindChildren<T>(child);
                    foreach (var item in children)
                        yield return item;
                }
            }
        }
    }
}

最后关于对象碰撞检测,推荐一篇不错的文章: http://www.andybeaulieu.com/Home/tabid/67/EntryID/160/Default.aspx 里面对于矢量对象的检测就是利用的FindElementsInHostCoordinates

VisualTreeHelper相关推荐

  1. WP8.1程序开发,可视树VisualTreeHelper类的使用

    对于可视树的使用,很久之前就接触了, 一方面当时知识太浅根本看不懂,就放下没看了: 另一方面,也没用到,就没往这方面努力研究学习: 现在好了,遇到问题了,正好涉及到VisualTreeHelper的使 ...

  2. WPF之ComboBox的VisualTreeHelper

    WPF之ComboBox的VisualTreeHelper 用WPF的ComboBox控件的时候,需要用到TextChanged属性,但是这个属性属于TextBox控件,不用担心,ComboBox中存 ...

  3. 使用VisualTreeHelper.GetDrawing(Visual v)枚举所有Visual内容的对象

    原文:使用VisualTreeHelper.GetDrawing(Visual v)枚举所有Visual内容的对象 C#代码:public void RetrieveDrawing(Visual v) ...

  4. WPF查找子控件和父控件方法

    原文:WPF查找子控件和父控件方法 public List<T> GetChildObjects<T>(DependencyObject obj, string name) w ...

  5. UWP: ListView 中与滚动有关的两个需求的实现

    在 App 的开发过程中,ListView 控件是比较常用的控件之一.掌握它的用法,能帮助我们在一定程度上提高开发效率.本文将会介绍 ListView 的一种用法--获取并设置 ListView 的滚 ...

  6. WPF怎么寻找在ItemTemplate内部的各种控件

    有如下控件 <Grid><ListBox x:Name="lb"><ListBox.ItemTemplate><DataTemplate& ...

  7. WPF拖放功能实现zz

    写在前面:本文为即兴而作,因此难免有疏漏和词不达意的地方.在这里,非常期望您提供评论,分享您的想法和建议. 这是一篇介绍如何在WPF中实现拖放功能的短文. 首先要读者清楚的一件事情是:拖放主要分为拖放 ...

  8. WPF MvvmLight简单实例(1) 页面导航

    原文:WPF MvvmLight简单实例(1) 页面导航 实现了那些功能,先看看截图: 操作描述: 在程序运行后,点击"Load"按钮,页面会加载PageOne,点击PageOne ...

  9. 分享Silverlight/WPF/Windows Phone一周学习导读(3月1日-3月5日)

    休假一个月,没有更新Silverlight/WPF/Windows Phone学习导读.从本周开始继续分享每周最新的Silverlight/WPF/Windows Phone开发学习导读. 本周Sil ...

最新文章

  1. [Python]小甲鱼Python视频第32课(except)课后题及参考解答
  2. adnroid 打包问题 :compileReleaseJavaWithJavac
  3. 大学士带你领略“大院大所”黑科技!
  4. 大根堆的删除c语言,小根堆大根堆的动态创建与堆顶元素删除
  5. linux socket通信编程之c语言(客户端和服务器程序)
  6. iOS越狱开发theOS搭建
  7. 抖音下拉词推广是什么?
  8. python 加速方法_加速Python的几种方法
  9. 小白错误三——Collider存在,刚体存在情况下,不能触发OnCollisionEnter函数
  10. php png 透明缩略图,php生成图片缩略图,支持png透明
  11. Java | PTA练习:Employee类的层级结构
  12. vPro里面的v代表什么意思?
  13. 存储历史(从古老的绳子记忆到如今)
  14. Intel IPP密码库 IPPCP 2018——第二部分 对称密码算法开发说明与示例代码
  15. 微生物组-宏基因组分析(线上/线下同时开课,2021.11)
  16. 0039c语言作业答案2020,中石油华东2020年秋季学期《程序设计(C语言)在线考试题目答案...
  17. W32TM注册time.windows.com作为权威时间同步源
  18. <el-upload>组件拖曳无法上传问题
  19. 源码分析 merge 标签减少布局层级的秘密(Android Q)
  20. 风水招财用品:貔貅的材质与区别

热门文章

  1. android渲染是skia与egl,Huang_Dongsung
  2. 利用深度学习识别番茄早期植株中的塔图绝对菌
  3. 【matlab】直方图均衡化
  4. 医疗中文问句意图匹配Top3方案ppt
  5. 前后端分离项目token怎么验证_前后端分离,获取token,验证登陆是否失效
  6. php验证注册不能纯数字,php写一个纯数字验证码教学
  7. winform 根据NAME查找控件
  8. 设计模式之十二:组合模式(composite)
  9. C++ ---------- map的使用
  10. Cocos2dx 下对sqlite3 的简单封装