4

UserControl名前付きのがあり、それには&の品揃えがAddressTemplate含まれています。私が必要としているのは、内のコントロールの1つの直接の祖先/親を見つける方法です。基本的に、与えられたものがの内側にあるのか、代わりにこれの外側にあり、単なるスタンドアロンコントロールであるのかを判断する方法が必要です。StackPanelLabelsTextboxesAddressTemplateTextboxAddressTemplateUserControl

私がこれまでに思いついたのはこれです:

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;            
    }

問題は、StackPanelをコントロールとしてキャストできないため、InvalidCastExceptionが発生し続けることです。誰かが適切なキャスト、またはこれを修正するための実行可能な方法を知っていますか?

4

2 に答える 2

7

LogicalTreeHelper.GetParentDependencyObjectを返すここで使用することをお勧めします。

//- 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 に答える