我在另一个UserControl
中有一个UserControl
'孩子'(在TabControl
中充当TabItem)。在子UserControl
和TabItem祖先之间有许多其他控件(例如:Grid
,StackPanel
,可能还有ScrollViewer
等)。
我想在我的孩子UserControl
中访问TabItem UserControl
的属性,并自定义commonly suggested递归函数,该函数沿Visual树移动。但是,这总是在第一次空检查时返回true
,直到我在逻辑树上添加查询为止。
代码:
public MyTabItem FindParentTabItem(DependencyObject child)
{
DependencyObject parent = VisualTreeHelper.GetParent(child) ?? LogicalTreeHelper.GetParent(child);
// are we at the top of the tree
if (parent == null)
{
return null;
}
MyTabItem parentTabItem = parent as MyTabItem;
if (parentTabItem != null)
{
return parentTabItem;
}
else
{
//use recursion until it reaches the control
return FindParentTabItem(parent);
}
}
不幸的是,它也返回null。单步执行该方法时,我发现它确实找到了正确的UserControl
TabItem,但是当它在返回值中递归(?)时,会将其还原为null,然后将其返回给调用方法(在子UserControl
的Loaded事件):
MyTabItem tab = FindParentTabItem(this);
如何解决此问题,以便我的方法正确返回找到的MyTabItem
?
答案 0 :(得分:0)
这是一个有效的经过单元测试的解决方案。
public static T FindAncestor<T>(DependencyObject obj)
where T : DependencyObject
{
if (obj != null)
{
var dependObj = obj;
do
{
dependObj = GetParent(dependObj);
if (dependObj is T)
return dependObj as T;
}
while (dependObj != null);
}
return null;
}
public static DependencyObject GetParent(DependencyObject obj)
{
if (obj == null)
return null;
if (obj is ContentElement)
{
var parent = ContentOperations.GetParent(obj as ContentElement);
if (parent != null)
return parent;
if (obj is FrameworkContentElement)
return (obj as FrameworkContentElement).Parent;
return null;
}
return VisualTreeHelper.GetParent(obj);
}
用法是
FindAncestor<MyTabItemType>(someChild);
编辑:
让我们假设您的xaml看起来像您所描述的一样:
<UserControl>
<Grid></Grid>
<StackPanel></StackPanel>
<!-- Probably also something around your child -->
<Grid>
<UserControl x:Name="child"/>
</Grid>
</UserControl>
您当前在您的child-xaml.cs中
void OnChildUserControlLoaded(object sender, RoutedEventArgs e)
{
var parent = FindAncestor<ParentUserControlType>(this);
DoSomething(parent.SomeProperty);
}
除非您执行某些操作,否则您不会描述代码将按原样运行。
建议您向MCVE提供所有必要的信息。