1

We have using the WPF popup control.

We need to know that how to calculate the distance / height or Y coordinate of Popup control from the Top of the screen. So, how to calculate it ?

Please see attached image for the issue screenshot.

Image for pop up with the issue

I tried two solutions as follows :

First solution -------------------------------------------------------

Window w = Application.Current.Point 
relativePoint = popNonTopMostPopup.TransformToAncestor(w)
                             .Transform(new Point(0, 0));

Issue: It is always returns the same coordinates as relativePoint.X = 3.0 and relativePoint.Y = 25.96
My popup cotrol opens at the right side of map icons as shown in image...so when i click on different map icon, popup position is changed accordingly. So it should return the different geo-coordnates.

Second solution ----------------------------------------------------

Point position = popNonTopMostPopup.PointToScreen(new Point(0d, 0d)),
controlPosition = this.PointToScreen(new Point(0d, 0d));
position.X -= controlPosition.X;
position.Y -= controlPosition.Y;

Issue: Same issue with this solution also..it is always returning same geocoordinate every time that are position.X = 3.0 and position.Y = 49.0

pankaj
  • 207
  • 6
  • 18

2 Answers2

0

You can use this:

TransformToAncestor as shown in here.

Point relativePointInWindow = yourPopup.TransformToAncestor(yourWindow)
                                       .Transform(new Point(0, 0));

Even in an UserControl you can access the parent

popup.parent.parent    
popup => usercontrol => window

Otherwise you can go with Application.Current.MainWindow to get your MainWindow.

You then go and get the position of your popup as shown above.

If needed you can add System.Windows.SystemParameters.CaptionHeight to the result.

This could look similar to this (untested):

public class MyMapArea : UserControl
{
    public MyMapArea()
    {

    }

    /// <summary>
    /// Returns the Y position relative to ScreenTop in Pixels
    /// </summary>
    private int GetYPositionOfPopup()
    {
        Popup popup = this.popup;

        Window window;

        FrameworkElement element;

        //Walk up the ui tree
        while(1 == 1)
        {
            //Remember to check for nulls, etc...
            element = this.parent;
            if(element.GetType() == typeof(Window))
            {
                //if you found the window set it to "window"
                window = (window)element;
                break;
            }
        }

        Point relativePointInWindow = popup.TransformToAncestor(window)
                                   .Transform(new Point(0, 0));

        return relativePointInWindow.Y // + System.Windows.SystemParameters.CaptionHeight;
    }
}
Felix D.
  • 4,811
  • 8
  • 38
  • 72
  • I need the distance between popup control and the Screen...not the top of the window. My pop up control is in user control and that user control is in dll so there will be no direct access to the window in our application. Is there any other solution ? thanks :) – pankaj Jun 23 '17 at 11:06
  • @pankaj see if that is what you need. – Felix D. Jun 23 '17 at 11:15
  • Hii @Felix D. I used your suggested code like this. Window w = Application.Current.MainWindow; Point relativePoint = popNonTopMostPopup.TransformToAncestor(w) .Transform(new Point(0, 0)); double x = relativePoint.X; double y = relativePoint.Y; – pankaj Jun 23 '17 at 11:39
  • @pankaj and ... ? Is it working ? Does the result seem to be correct ? – Felix D. Jun 23 '17 at 11:40
  • No its not working...it is always returning the same coordinates that is for X = 3 and for Y = 25.96.....but my pop up control opens at different places every time when i click on different map icon. @Felix D – pankaj Jun 23 '17 at 11:44
  • @pankaj can you please update your question with the code you are currently using ? – Felix D. Jun 23 '17 at 11:50
  • Thanks for the link @Felix D....but facing same problem here also...i am always getting same values for position.X = 3.0 and position.Y = 49.0 – pankaj Jun 23 '17 at 11:56
0

The following logic can calculate the position of a control inside the popup. It can make the calculation after the popup is displayed (otherwise the source will be null).

When you display the content of a popup you are in a different visual tree, so there is no point to do any calculation with the original Popup object.

var source = PresentationSource.FromVisual(controlInsidePopup);
if (source == null)
  return;

// Get absolute location on screen of upper left corner of the control
var locationFromScreen = controlInsidePopup.PointToScreen(new Point(0, 0));

var targetPoints = source.CompositionTarget.TransformFromDevice.Transform(locationFromScreen);

string positionInfo = $"Current Position X: {targetPoints.X}, Y: {targetPoints.Y}";

The code is a slightly modified logic taken from here: https://social.msdn.microsoft.com/Forums/vstudio/en-US/281a8cdd-69a9-4a4a-9fc3-c039119af8ed/absolute-screen-coordinates-of-wpf-user-control?forum=wpf

BalintPogatsa
  • 129
  • 1
  • 5