4

我有一个UserControlnamed AddressTemplate,其中包含 aStackPanel和各种Labels& Textboxes。我需要的是一种在AddressTemplate. 本质上,我需要一种方法来确定给定Textbox是否在内部AddressTemplate,或者在外部UserControl,并且只是一个独立的控件。

到目前为止,我想出的是:

private bool FindParent(Control target)
    {
        Control currentParent = new Control();

        if (currentParent.GetType() == typeof(Window))
        {

        }
        else if (currentParent.GetType() != typeof(AddressTemplate) && currentParent.GetType() != null)
        {
            currentParent = (Control)target.Parent;
        }
        else
        {
            return true;
        }

        return false;            
    }

问题是,我不断收到 InvalidCastException,因为它无法将 StackPanel 转换为控件。有谁知道正确的演员阵容,或者解决这个问题的可行方法?

4

2 回答 2

7

你可能想在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上 Wpf中的树

于 2012-04-26T15:37:51.687 回答
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
}
于 2012-04-26T15:47:21.313 回答