自己写了一个方法, 通过可视树遍历子节点,然后匹配名字。 如下:
private static ChildItem FindVisualChildItem<ChildItem>(DependencyObject obj) where ChildItem : DependencyObject { if (null != obj) { for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++) { DependencyObject child = VisualTreeHelper.GetChild(obj, i); if (child != null && child is ChildItem) return (ChildItem)child; else { ChildItem childOfChild = FindVisualChildItem<ChildItem>(child); if (childOfChild != null) return childOfChild; } } } return null; } private static ChildItem FindVisualChildItem<ChildItem>(DependencyObject obj, string name) where ChildItem : FrameworkElement { if (null != obj) { for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++) { DependencyObject child = VisualTreeHelper.GetChild(obj, i); if (child != null && child is ChildItem && (child as ChildItem).Name.Equals(name)) { return (ChildItem)child; } else { ChildItem childOfChild = FindVisualChildItem<ChildItem>(child, name); if (childOfChild != null && childOfChild is ChildItem && (childOfChild as ChildItem).Name.Equals(name)) { return childOfChild; } } } } return null; }
今天无意中发现系统FrameworkElement自带了一个方法
GetTemplateChild
此方法同样实现了根据名字来获取控件模板里的子节点。 反编译PresentaitionFramework,源码如下:
protected internal DependencyObject GetTemplateChild(string childName)
{
FrameworkTemplate templateInternal = this.TemplateInternal;
if (templateInternal == null)
{
return null;
}
return StyleHelper.FindNameInTemplateContent(this, childName, templateInternal) as DependencyObject;
}
internal static object FindNameInTemplateContent(DependencyObject container, string childName, FrameworkTemplate frameworkTemplate)
{
int num = StyleHelper.QueryChildIndexFromChildName(childName, frameworkTemplate.ChildIndexFromChildName);
if (num == -1)
{
Hashtable @value = StyleHelper.TemplatedNonFeChildrenField.GetValue(container);
if (@value != null)
{
return @value[childName];
}
}
return null;
return StyleHelper.GetChild(container, num);
}
主要是
childIndexFromChildName根据name来查询index,然后根据index获取对应子节点。