我有一个名为UserControl
的{{1}},其中包含一个AddressTemplate
,其中包含各种StackPanel
& Labels
。我需要的是找到Textboxes
中某个控件的直接祖先/父级的方法。从本质上讲,我需要一种方法来确定给定AddressTemplate
是否在Textbox
内,或者在AddressTemplate
之外,并且只是一个独立的控件。
到目前为止,我想出的是:
UserControl
问题是,我不断收到InvalidCastException,因为它无法将StackPanel强制转换为Control。有没有人知道正确的演员,或者解决这个问题的可行方法?
答案 0 :(得分:6)
你可能想在这里使用LogicalTreeHelper.GetParent
,它返回一个DependencyObject:
//- warning, coded in the SO editor window
private bool IsInAddressTemplate(DependencyObject target)
{
DependencyObject current = target;
Type targetType = typeof(AddressTemplate);
while( current != null)
{
if( current.GetType() == targetType)
{
return true;
}
current = LogicalTreeHelper.GetParent(current);
}
return false;
}
这将向上走逻辑父树,直到找不到您要查找的父级或用户控件。有关详细信息,请查看MSDN上的Trees in Wpf
答案 1 :(得分:2)
我使用下面的扩展方法,通过在可视树上走来创建所有视觉父母的IEnumerable
:
public static IEnumerable<DependencyObject> VisualParents(this DependencyObject element)
{
element.ThrowIfNull("element");
var parent = GetParent(element);
while (parent != null)
{
yield return parent;
parent = GetParent(parent);
}
}
private static DependencyObject GetParent(DependencyObject element)
{
var parent = VisualTreeHelper.GetParent(element);
if (parent == null && element is FrameworkElement)
parent = ((FrameworkElement)element).Parent;
return parent;
}
这非常灵活。在您的示例中,您可以按如下方式使用它:
if (target.VisualParents().OfType<AddressTemplate>().Any()) {
//the target is in the address template
}