简体   繁体   English

如何在wpf中计算弹出控件和屏幕顶部之间的距离?

[英]How to calculate distance between popup control and Top of the screen in wpf?

We have using the WPF popup control. 我们使用WPF弹出控件。

We need to know that how to calculate the distance / height or Y coordinate of Popup control from the Top of the screen. 我们需要知道如何从屏幕顶部计算Popup控件的距离/高度或Y坐标。 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 问题:始终返回与relativePoint.X = 3.0和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. 所以它应该返回不同的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 问题:此解决方案也存在同样的问题..每次位置时总是返回相同的地理坐标.X = 3.0和position.Y = 49.0

You can use this: 你可以用这个:

TransformToAncestor as shown in here . TransformToAncestor如图这里

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

Even in an UserControl you can access the parent 即使在UserControl您也可以访问父级

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

Otherwise you can go with Application.Current.MainWindow to get your MainWindow. 否则,您可以使用Application.Current.MainWindow来获取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. 如果需要,可以将System.Windows.SystemParameters.CaptionHeight添加到结果中。

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

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). 它可以在显示弹出窗口后进行计算(否则源将为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. 当您显示弹出窗口的内容时,您位于不同的可视树中,因此无需使用原始Popup对象进行任何计算。

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 代码是一个稍微修改过的逻辑,取自这里: https//social.msdn.microsoft.com/Forums/vstudio/en-US/281a8cdd-69a9-4a4a-9fc3-c039119af8ed/absolute-screen-coordinates-of-wpf -user控制?论坛= WPF

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM