3

I have two questions on markup below:

<Popup>
    <Button x:Name="button"/>
</Popup>
  1. Why does VisualTreeHelper.GetParent(button) return null?
  2. How can I get the parent Popup for UIElement?
Dave Clemmer
  • 3,741
  • 12
  • 49
  • 72
altso
  • 2,311
  • 4
  • 26
  • 40

5 Answers5

5

Instead of going through the VisualTree, have you just tried a while loop to walk up the .Parents for the elements?

    private void TryClosePopupParent(object o)
    {
        while (o != null)
        {
            Popup p = (o as Popup);
            if(p == null)
            {
                o = (o as FrameworkElement).Parent;
            }
            else 
            {
                p.IsOpen = false;
                break;
            }
        }
    }

I haven't ever tested it on something that doesn't have a PopUp as a parent, but it worked for me.

Dave Clemmer
  • 3,741
  • 12
  • 49
  • 72
Henry C
  • 4,781
  • 4
  • 43
  • 83
3
  1. Because the Button is only added to the visual tree when the popup is being displayed.

  2. Hmm... tricky ...

Edit

There is an assumption in the following that your popup is defined in the XAML of UserControl so whilst its child may not be in the visual tree the popup primitive control is.

Re-using some code I've posted before (I really must get me a blog).

public static class VisualTreeEnumeration
{
    public static IEnumerable<DependencyObject> Descendents(this DependencyObject root)
    {
        int count = VisualTreeHelper.GetChildrenCount(root);
        for (int i = 0; i < count; i++)
        {
            var child = VisualTreeHelper.GetChild(root, i);
            yield return child;
            foreach (var descendent in Descendents(child))
                yield return descendent;
        }
    }
}

This adds an extension method to the DependencyObject which uses the VisualTreeHelper to unify the search for objects added in the visual tree. So in the usercontrol code behind you can do this:-

var popup this.Descendents()
        .OfType<Popup>()
        .Where(p => p.Child == button)
        .FirstOrDefault();

This will find the Popup which is the parent of "button".

Dave Clemmer
  • 3,741
  • 12
  • 49
  • 72
AnthonyWJones
  • 187,081
  • 35
  • 232
  • 306
  • Even with opened popup GetParent method returns null – altso Jan 05 '10 at 17:04
  • Hmm... yes that is true, it is at the top of a tree which is displayed on top the existing visuals. Hence the Offsets being relative the Silverlight control itself. – AnthonyWJones Jan 05 '10 at 17:19
1

Popup control is very annoying sometimes. And I have no idea at the moment why VisualTreeHelper.GetParent(button) returns null. But for the second this may help.

Dave Clemmer
  • 3,741
  • 12
  • 49
  • 72
zihotki
  • 5,201
  • 22
  • 26
1

zihotki's solution looks promising (i haven't tested it).

Although VisualTreeHelper.GetParent(button) returns null, you can use button.Parent, which should give you the popup object.

Dave Clemmer
  • 3,741
  • 12
  • 49
  • 72
RobSiklos
  • 8,348
  • 5
  • 47
  • 77
0

Make sure that the PopUp is attached to the VisualTree. Find more information on this in the Remarks section http://msdn.microsoft.com/en-us/library/system.windows.controls.primitives.popup(v=vs.95).aspx

Dave Clemmer
  • 3,741
  • 12
  • 49
  • 72
Trident D'Gao
  • 18,973
  • 19
  • 95
  • 159