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\下
如下图:
@H_616_42@
从上图可以看到,
一个普通的Button控件,在可视化(对象)树里表现为:But
tomcathrome,ContentPresenter,TextBlock的组合
另外Silverlight中提供了一个VisualTreeHelper工具类,用于操作可视化树,里面有4个静态方法:
官方解释如下:
FindElementsInHostCoordinates 检索一组对象,这些对象位于某一对象的坐标空间的指定点或 Rect 内。
GetChild 使用提供的索引,通过检查可视化树获取所提供对象的特定子对象。
GetChildrenCount 返回在可视化树中在某一对象的子集合中存在的子级的数目。
GetParent 返回可视化树中某一对象的父对象。
通俗点说:FindElementsInHostCoordinates常用于对象的碰撞检测,GetChild用于获取下级子对象(注意仅仅是下级,而非所有子对象,如果要获取所有子对象,需要自己写代码遍历),GetChildrenCount用于获取下级子对象的个数,GetParent用于获取某对象的上级子对象
测试代码:
代码
<
UserControl
x:Class
="ToolsTest.MainPage"
xmlns
="http://scheR_205_11845@as.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x
="http://scheR_205_11845@as.microsoft.com/winfx/2006/xaml"
xmlns:d
="http://scheR_205_11845@as.microsoft.com/expression/blend/2008"
xmlns:mc
="http://scheR_205_11845@as.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable
="d"
d:DesignWidth
="640"
d:DesignHeight
="480"
>
Grid
x:Name
="LayoutRoot"
StackPanel
="sp"
HorizontalAlignment
="Left"
TextBlock
Text
="Test textBlock"
Height
="25"
Width
="100"
x:Name
="txt"
></
TextBlock
Button
="btn1"
Content
="button1"
Button
="sp2"
="btn2"
="button2"
</
StackPanel
="btn3"
="button3"
="btnClick"
="Test"
="22"
="80"
="Center"
VerticalAlignment
="Bottom"
Click
="btnClick_Click"
Grid
UserControl
>
代码
using
System.Linq;
System.Windows;
System.Collections.Generic;
System.Windows.Controls;
System.Windows.Media;
namespace
ToolsTest
{
public
partial
class
MainPage : UserControl
{
MainPage()
{
initializeComponent();
}
private
void
btnClick_Click(
object
sender, routedEventArgs E)
{
int
_childCount
=
VisualTreeHelper.GetChildrenCount(
this
);
messageBox.Show(
"
@H_242_82
@mainPage下级子对象总数:
"
+
_childCount.ToString());
//
就是一个Grid,所以返回1
IEnumerable
<
>
AllButtons
FindChildren
(
);
得到所有的Buttons
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(
{0}的上级对象是{1}
:12px; line-height:1.5; color:rgb(128,btn2.Content,sp.Name));
rect rect
new
rect(
:12px; line-height:1.5; color:rgb(128,
100
25
);
IEnumerable
UIElement
check
VisualTreeHelper.FindElementsInHostCoordinates(rect,
);
检测MainPage的0,0到100,25矩形区域内有哪些元素
(UIElement item
check)
{
_name
item.GetValue(NameProperty).ToString();
if
(_name.Length
)
{
messageBox.Show(_Name);
}
}
}
///
<sumMary>
来自博客园"木野狐"的特定类型子对象方法
</sumMary>
<typeparam NAME="T"></typeparam>
<param NAME="parent"></param>
<returns></returns>
IEnumerable
T
(DependencyObject parent)
where
T :
{
var count
VisualTreeHelper.GetChildrenCount(parent);
(count
)
{
for
(var i
; i
count; i
)
{
var child
VisualTreeHelper.GetChild(parent, i);
var t
child
T;
(t
!=
null
)
yield
return
t;
var children
(child);
(var item
children)
item;
}
}
}
}
}
最后关于对象碰撞检测,推荐一篇不错的文章: http://www.andybeaulieu.com/Home/tabid/67/EntryID/160/Default.aspx 里面对于矢量对象的检测就是利用的FindElementsInHostCoordinates