WPF:在屏幕坐标和WPF坐标之间转换 [英] WPF: Converting between screen coordinates and WPF coordinates

查看:984
本文介绍了WPF:在屏幕坐标和WPF坐标之间转换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道,如果计算机未使用默认的DPI设置,则WPF坐标与实际屏幕的坐标(像素坐标)不同。在我的程序中,我想(1)确定哪个监视器打开了WPF窗口,并且(2)在同一监视器的左下角打开另一个窗口。我听说没有屏幕 WPF,所以我使用WinForms版本,如下所示,它在默认的96 DPI下可以正常工作:

I understand that WPF coordinates are different from "real" screen coodinates (pixel coordinates) if the computer is not using the default DPI setting. In my program I want to (1) figure out which monitor a WPF window is on and (2) open another window in the bottom-left corner of the same monitor. I heard there is no equivalent of Screen for WPF so I use the WinForms version, as follows, which works fine at the default 96 DPI:

public void ChooseInitialPosition(Window w) // w is some other window
{
    var scr = System.Windows.Forms.Screen.FromRectangle(
          new System.Drawing.Rectangle((int)w.Left, (int)w.Top, (int)w.Width, (int)w.Height))
          .WorkingArea;

    this.Left = scr.Right - Width;
    this.Top = scr.Bottom - Height;
}

但是在其他DPI上,这两个步骤均无法正常工作,并且可能会使窗口完全消失

But at other DPIs, both steps work incorrectly, and may put the window completely off-screen.

到目前为止,看来我可以使用 Visual.PointToScreen 第一部分:

So far, it looks like I can use Visual.PointToScreen for the first part:

var p1 = w.PointToScreen(new Point(0,0));
var p2 = w.PointToScreen(new Point(w.Width,w.Height));
var scr = System.Windows.Forms.Screen.FromRectangle(
    new System.Drawing.Rectangle((int)p1.X, (int)p1.Y, (int)(p2.X - p1.X), (int)(p2.Y - p1.Y))).WorkingArea;

我不确定这是否正确,因为它可能无法正确说明边界。但是第二部分更重要。如何将屏幕矩形 scr转换为WPF空间,以便正确设置 Left和 Top?

I'm not sure if this is quite right, as it may not account for the borders correctly. But the second part is more important. How do I convert the screen rectangle "scr" into WPF space, in order to set Left and Top correctly?

推荐答案


  1. 打开了WPF窗口的哪个屏幕:

  1. Which screen a WPF window is on:

private static Screen GetScreen(Window window)
{
   return Screen.FromHandle(new WindowInteropHelper(window).Handle);
}


  • 在同一屏幕的左下角打开另一个窗口:

  • Open another window in the bottom-left corner of the same screen:

    static Point RealPixelsToWpf(Window w, Point p)
    {
        var t = PresentationSource.FromVisual(w).CompositionTarget.TransformFromDevice;
        return t.Transform(p);
    }
    private static void SetPositionBottomLeftCorner(Window sourceWindow, Window targetWindow)
    {
        var workingArea = GetScreen(sourceWindow).WorkingArea;
        var corner = RealPixelsToWpf(sourceWindow, new Point(workingArea.Left, workingArea.Bottom));
        targetWindow.Left = corner.X;
        targetWindow.Top = corner.Y - targetWindow.ActualHeight;
    }
    


  • 这篇关于WPF:在屏幕坐标和WPF坐标之间转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆