Popup positioning? RRS feed

  • Question

  • Is it possible to tell if a popup that's launched from an object will fit within the screen real estate?  

    The basic behavior of a popup is that if there is no room left on the screen for the popup to show below an object it is attached to, it will automatically move above the object so it can be seen and won't push outside the screen boundaries.  Is there a way to tell if the popup will be able to fit or not?  

    I want to be able to reposition some elements in the popup template if it automatically shifts above the object that it's attached to. 
    Wednesday, August 27, 2008 5:47 PM

All replies

  • I'd make my own popup control.

    Mostly because Popup has TopMost wich is quite anoying when "someone" forgets to close it.

    Bigsby, Lisboa, Portugal
    Monday, September 1, 2008 4:50 PM
  • If I am not mistaken, Popup has built-in support for proper screen positioning, aka it will always display itself in the right place without being shown off screen, or you need something beyond what Popup has been provided?

    Tuesday, September 2, 2008 3:27 AM
  • Well, actually yes ... basically I've overridden the default style of the popup - I've created a popup that has a "tab" on one side that effectively points to the object that launched the popup.  My problem is that if the popup auto positions itself on top of the element due to screen boundary restrictions, I need to move the tab portion in my control template.  Unfortunately I can't seem to find a way of knowing whether the popup has automatically positioned itself or not ...

    any ideas?
    Tuesday, September 2, 2008 4:18 PM
  • If you're having that much trouble with it, maybe it's time to make your own Popup control.

    I, myself, don't fancy ToolTip and Popup controls because of their topmost property.

    Bigsby, Lisboa, Portugal
    Tuesday, September 2, 2008 5:50 PM
  • -> My problem is that if the popup auto positions itself on top of the element due to screen boundary restrictions, I need to move the tab portion in my control template.  Unfortunately I can't seem to find a way of knowing whether the popup has automatically positioned itself or not ...

    I am not clear what you mean by "tab" here, and which positioning requirement you have, Popup has provided many positioning knobs which you could tweak to implement custom positioning, please refer to the following MSDN documentation for more information:

    Hope that helps
    Wednesday, September 3, 2008 3:33 AM
  • If you can imagine, my popup looks a bit like a "balloon" tooltip ... the "tab" I'm referring to is basically like the "call out" piece of a tooltip - the little arrow thing that points to the object.

    My call out, or "tab" is on the left hand side of the control ... and I use custom placement to place the popup just to the right of the control that was clicked on.  It all works completely fine and the tab lines up correctly to the element ... until the popup starts repositioning itself.

    The popup will reposition itself without any of my help, regardless of custom placement methods IF it can't fit inside the screen resolution.  In other words, if the object that launches the popup is at the bottom of the screen, the popup won't have room to fit vertically ... so it repositions itself above the object so it can be seen.  This is fine, but I then need to reposition my little "tab" so that it still lines up with the control.  My problem is that I have no idea when the popup plans on doing this vertical repositioning act ... unless I do a whole bunch of screen calculations, which i just might have to do.
    Wednesday, September 3, 2008 5:19 PM
  • My company has run into this too. The Popup class really needs a property which one can bind to, that reflects the actual placement of the popup relative to its target, for just these situations.

    Microsoft: take heed.
    Controls for WPF and Windows Forms at
    Wednesday, September 3, 2008 10:25 PM
  • I agree. 

    And I just realized I won't be able to figure this out even by doing screen calculations - because I don't know how large the popup will be until it's actually instantiated.   Unfortunately I don't have time to try and build a custom control that would mimic a popup as well ...
    Thursday, September 4, 2008 5:57 PM
  • Have you looked at CustomPopupPlacementCallback? By setting Placement to Custom and providing a callback, you might be able to use the information provided in the callback as well as screen information to determine if your popup will fit on-screen.

    Unfortunately, I don't have any information on when we will be making improvements to Popup, but I will add this scenario to our list.

    This posting is provided "AS IS" with no warranties, and confers no rights.
    Saturday, September 6, 2008 1:28 AM
  • Ben - i'm not sure what you mean by using the information provided in the callback - can u provide a small snippet to describe what you're referring to?
    Monday, September 8, 2008 4:54 PM
  • CustomPopupPlacementCallback provides the size of the popup, the size of the PlacementTarget, and the value of HorizontalOffset and VerticalOffset. You will essentially be performing the positioning logic of the Popup, which is not a small amount of work, but less than rewriting the whole control.

    The general outline is to transform all of the sizes and positions to screen coordinates. Choose a set of possible positions and see if the popup will fit on-screen at those positions. Depending on which position is chosen, adjust your content.

    You will want your handler to be on an instance of an object that contains references to the Popup and/or the PlacementTarget so that you can call TransfromToAncestor.
    Visual rootVisual = PresentationSource.FromVisual(PlacementTarget).CompositionTarget.RootVisual;
    GeneralTransform transform = PlacementTarget.TransformToAncestor(rootVisual);
    Point upperLeftPlacementTarget = transform.Transform(new Point(0, 0));
    Point lowerRightPlacementTarget = transform.Transform((Point)targetSize);

    In order to convert from device independent units to device units, you will need access to the CompositionTarget:
    GeneralTransform deviceTransform = PresentationSource.FromVisual(PlacementTarget).CompositionTarget.TransformToDevice;
    upperLeftPlacementTarget = deviceTransform.Transform(upperLeftPlacementTarget);
    lowerRightPlacementTarget = deviceTransform.Transform(lowerRightPlacementTarget);
    Point devicePopupSize = deviceTransform.Transform.Transform((Point)popupSize);

    From here, you can choose where the popup might go (such as at upperLeftPlacementTarget.X, lowerRightPlacementTarget.Y) and compare the final popup rectangle with the monitor rectangle. For that, you'll need to use the unmanaged Win32 APIs MonitorFromRect (using the PlacementTarget device bounds) and GetMonitorInfo (which will contains the monitor's rectangle).

    This should let you figure out before the window is open where the popup will appear. If you decide that figuring this out after the fact is also acceptable, then you can use these same APIs to determine where the popup actually is relative to the PlacementTarget.

    This posting is provided "AS IS" with no warranties, and confers no rights.
    Monday, September 8, 2008 5:57 PM