Silverlight 中有所谓视觉树(Visual Tree)的概念,而 VisualTree 是一个运行时的概念,其实可以理解为一种 DOM.
其内容的来源可以是几个方面:
1.静态 XAML 文件中创建的。
2.用 XamlReadler.Load() 方法动态加载的 XAML 内容。
3.完全通过代码创建的控件。
在 XAML 中我们通过 x:Name 来标识一个元素,但是光靠 Name 不能解决全部的问题,特别对于一些动态的场景而言。
有时候我们还需要根据控件的类型或者其他条件来查找节点。
比如:
“ 给我找出当前这个控件在哪个 Tab 页(TabItem)中”
“ 找出祖先控件中谁实现了 IDialogHost 接口(准备显示一个对话框加载当前用户控件的内容)”
等等类似的需求。
于是就有了下面两个方法:
使用方法很简单。比如(还是拿对话框来举例):
over.
其内容的来源可以是几个方面:
1.静态 XAML 文件中创建的。
2.用 XamlReadler.Load() 方法动态加载的 XAML 内容。
3.完全通过代码创建的控件。
在 XAML 中我们通过 x:Name 来标识一个元素,但是光靠 Name 不能解决全部的问题,特别对于一些动态的场景而言。
有时候我们还需要根据控件的类型或者其他条件来查找节点。
比如:
“ 给我找出当前这个控件在哪个 Tab 页(TabItem)中”
“ 找出祖先控件中谁实现了 IDialogHost 接口(准备显示一个对话框加载当前用户控件的内容)”
等等类似的需求。
于是就有了下面两个方法:
using
System.Collections.Generic;
using System.Windows;
using System.Windows.Media;
namespace NeilChen.SilverlightExtensions
{
public static class DomExtensions
{
/// <summary>
/// 查找祖先节点
/// </summary>
/// <typeparam name="T"> 目标节点的类型 </typeparam>
/// <param name="child"> 起始节点 </param>
/// <returns></returns>
public static T FindAncestor < T > ( this DependencyObject child) where T : class
{
var d = VisualTreeHelper.GetParent(child);
while (d != null && ! (d is T))
{
d = VisualTreeHelper.GetParent(d);
}
return d as T;
}
/// <summary>
/// 查找某种类型的子孙节点
/// </summary>
/// <typeparam name="T"> 目标节点类型 </typeparam>
/// <param name="parent"> 起始节点 </param>
/// <returns> 符合条件的节点集合 </returns>
public static IEnumerable < T > FindChildren < T > ( this 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;
}
}
}
}
}
using System.Windows;
using System.Windows.Media;
namespace NeilChen.SilverlightExtensions
{
public static class DomExtensions
{
/// <summary>
/// 查找祖先节点
/// </summary>
/// <typeparam name="T"> 目标节点的类型 </typeparam>
/// <param name="child"> 起始节点 </param>
/// <returns></returns>
public static T FindAncestor < T > ( this DependencyObject child) where T : class
{
var d = VisualTreeHelper.GetParent(child);
while (d != null && ! (d is T))
{
d = VisualTreeHelper.GetParent(d);
}
return d as T;
}
/// <summary>
/// 查找某种类型的子孙节点
/// </summary>
/// <typeparam name="T"> 目标节点类型 </typeparam>
/// <param name="parent"> 起始节点 </param>
/// <returns> 符合条件的节点集合 </returns>
public static IEnumerable < T > FindChildren < T > ( this 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;
}
}
}
}
}
使用方法很简单。比如(还是拿对话框来举例):
IDialogHost host
=
this
.FindAncestor
<
IDialogHost
>
();
if (host != null )
{
host.ShowModalDialog( this );
}
if (host != null )
{
host.ShowModalDialog( this );
}
over.