您的位置:首页 > 其它

VisualTreeHelper

2010-01-02 21:31 288 查看
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\下

如下图:

代码

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: