適用WPF,部分適用於Silverlight。
using System;
using System.Diagnostics;
using System.Windows;
using System.Windows.Media;
namespace OrcaPlayer.Common
{
public class TreeHelper
{
private static object _SyncRoot = new object();
<summary>
IsolatedStorageHelper Static Constructor.
</summary>
static TreeHelper()
{
}
private static TreeHelper _instance = null;
<summary>
</summary>
public static TreeHelper Instance
{
get
{
lock (_SyncRoot)
{
if (_instance == null)
{
_instance = new TreeHelper();
}
return _instance;
}
}
}
public DependencyObject FindVirtualTreeRoot(DependencyObject initial)
{
DependencyObject current = initial;
DependencyObject result = initial;
while (current != null)
{
result = current;
if (current is Visual || current is Visual3D)
{
current = VisualTreeHelper.GetParent(current);
}
else
{
current = LogicalTreeHelper.GetParent(current);
}
}
return result;
}
public DependencyObject FindLogicalTreeRoot(DependencyObject initial)
{
DependencyObject current = initial;
DependencyObject result = initial;
while (current != null)
{
result = current;
current = LogicalTreeHelper.GetParent(current);
}
return result;
}
//using System.Windows;
public DependencyObject GetTemplateParent(DependencyObject depObj)
{
FrameworkElement fe = depObj as FrameworkElement;
FrameworkContentElement fce = depObj as FrameworkContentElement;
DependencyObject result;
if (fe != null)
{
result = fe.TemplatedParent;
}
else if (fce != null)
{
result = fce.TemplatedParent;
}
else
{
result = null;
}
return result;
}
//最近邏輯樹上的父節點
public DependencyObject FindClosestLogicalAncestor(DependencyObject initial)
{
DependencyObject current = initial;
DependencyObject result = initial;
while (current != null)
{
DependencyObject logicalParent = LogicalTreeHelper.GetParent(current);
if (logicalParent != null)
{
result = current;
break;
}
current = VisualTreeHelper.GetParent(current);
}
return result;
}
//最近視覺樹上的父節點
public DependencyObject FindClosestVisualAncestor(DependencyObject initial)
{
if (initial is Visual || initial is Visual3D)
{
return initial;
}
DependencyObject current = initial;
DependencyObject result = initial;
while (current != null)
{
result = current;
if (current is Visual || current is Visual3D)
{
result = current;
break;
}
else
{
current = LogicalTreeHelper.GetParent(current);
}
}
return result;
}
//顯示邏輯樹
//private TreeView tree = new TreeView();
public void PopulateLogicalTree(TreeViewItem parentItem, object currentElement)
{
TreeViewItem item = new TreeViewItem();
item.IsExpanded = true;
if (parentItem == null)
{
item.Header = currentElement.GetType().Name;
tree.Items.Add(item);
}
else
{
item.Header = currentElement.GetType().Name;
parentItem.Items.Add(item);
}
DependencyObject curObject = currentElement as DependencyObject;
if (curObject != null)
{
foreach (object chElement in LogicalTreeHelper.GetChildren(curObject))
{
PopulateLogicalTree(item, chElement);
}
}
}
//顯示視覺樹
//private TreeView tree = new TreeView();
public void PopulateVisualTree(TreeViewItem parentItem, DependencyObject currentElement)
{
TreeViewItem item = new TreeViewItem();
item.IsExpanded = true;
if (parentItem == null)
{
item.Header = currentElement.GetType().Name;
tree.Items.Add(item);
}
else
{
item.Header = currentElement.GetType().Name;
parentItem.Items.Add(item);
}
int visualChildrenCount = VisualTreeHelper.GetChildrenCount(currentElement);
for (int i = 0; i < visualChildrenCount; i++)
{
DependencyObject visualChild = VisualTreeHelper.GetChild(currentElement, i);
PopulateVisualTree(item, visualChild);
}
}
//ex: CheckBox chb = this.FindFirstVisualChild<CheckBox>(listViewItem)
public T FindFirstVisualChild<T>(DependencyObject parentElement) where T : DependencyObject
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parentElement); i++)
{
DependencyObject child = VisualTreeHelper.GetChild(parentElement, i);
if (child != null && child is T)
{
return child as T;
}
else
{
T result = FindFirstVisualChild<T>(child);
if (result != null)
{
return result;
}
}
}
return null;
}
//TextBlock textBlock = GetFrameworkElementByName<TextBlock>(rowPresenter, "textBlock");
public T GetFrameworkElementByName<T>(FrameworkElement parentElement, String name) where T : FrameworkElement
{
FrameworkElement child = null;
for (Int32 i = 0; i < VisualTreeHelper.GetChildrenCount(parentElement); i++)
{
Debug.WriteLine("TreeHelper.cs::GetFrameworkElementByName " + parentElement.GetType().ToString() + " " + i.ToString());
child = VisualTreeHelper.GetChild(parentElement, i) as FrameworkElement;
if (child != null && child.Name == name && child.GetType() == typeof(T))
{
break;
}
else if (child != null)
{
child = GetFrameworkElementByName<T>(child, name);
}
}
return child as T;
}
//ContentPresenter cp = VisualTreeHelper.GetChild(CInfoContentControl, 0) as ContentPresenter;
//Button DownloadButton = TreeHelper.Instance.FindVisualChild<Button>(cp, 0, 3, 0, 0, 1) as Button;
//第二參數為第一參數下的的每一層子元素(子元素從0起算)
public T FindVisualChild<T>(DependencyObject parentElement, params int[] list) where T : DependencyObject
{
DependencyObject child = null;
for (int i = 0; i < list.Length; i++)
{
Debug.WriteLine("i=[" + i.ToString() + "] list[i]=[" + list[i].ToString() + "]");
if (i == 0)
{
if (VisualTreeHelper.GetChildrenCount(parentElement) > 0)
{
child = VisualTreeHelper.GetChild(parentElement, list[0]);
Debug.WriteLine("子元素型別=[" + child.GetType().ToString() + "]");
}
else
{
Debug.WriteLine(i.ToString() + " 子元素個數=[" + VisualTreeHelper.GetChildrenCount(parentElement).ToString() + "]");
}
}
else
{
if (VisualTreeHelper.GetChildrenCount(child) > 0)
{
child = VisualTreeHelper.GetChild(child, list[i]);
Debug.WriteLine("子元素型別=[" + child.GetType().ToString() + "]");
}
else
{
Debug.WriteLine(i.ToString() + " 子元素個數=[" + VisualTreeHelper.GetChildrenCount(child).ToString() + "]");
}
}
}
if (child != null && child is T)
{
return child as T;
}
else
{
return null;
}
}
public static T GetValue<T>(this BindingExpression expression, object dataItem)
{
if (expression == null || dataItem == null)
{
return default(T);
}
string bindingPath = expression.ParentBinding.Path.Path;
string[] properties = bindingPath.Split('.');
object currentObject = dataItem;
Type currentType = null;
for (int i = 0; i < properties.Length; i++)
{
currentType = currentObject.GetType();
PropertyInfo property = currentType.GetProperty(properties[i]);
if (property == null)
{
currentObject = null;
break;
}
currentObject = property.GetValue(currentObject, null);
if (currentObject == null)
{
break;
}
}
return (T)currentObject;
}
}
}
參考資料: