wPF VisualTreeHelper.GetParent returns wrong class?

Viewed 10546

I have the following XAML defined.

<Popup x:Class="EMS.Controls.Dictionary.MapTip"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"   
    PopupAnimation="Slide"
     AllowsTransparency="True" Placement="Mouse"       
       x:Name="root"                   
      >

    <Popup.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="../Resources/Styles.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Popup.Resources>
    <Viewbox x:Name="viewBox" IsHitTestVisible="True">
        <Grid Background="Transparent" Name="mainGrid">

        </Grid>
    </Viewbox>
</Popup>

If I walk up the visual tree using VisualTreeHelper.GetParent from "mainGrid", I eventually get System.Windows.Controls.Primitives.PopupRoot, but never get the Popup itself. Anyone with a theory on why this is and what I can do about it? I neeed Popup and not PopupRoot.

TIA.

6 Answers

Based on this answer and the answers presented here (and thanks to a comment by Wouter), I finally came up with this:

using System.Windows.Media;
using System.Windows.Media.Media3D;

public static class FamilyHelper
{
    public static T FindAncestor<T>(this DependencyObject dObj) where T : DependencyObject
    {
        var uiElement = dObj;
        while (uiElement != null)
        {
            uiElement = VisualTreeHelper.GetParent(uiElement as Visual ?? new UIElement())
                ?? VisualTreeHelper.GetParent(uiElement as Visual3D ?? new UIElement())
                ?? LogicalTreeHelper.GetParent(uiElement);

            if (uiElement is T) return (T) uiElement;
        }
        return null;
    }
}

which never goes wrong and works for all types of controls, e.g.

var element = sender as UIElement;
var parentWindow = element.FindAncestor<Window>();
Related