Dot-Net

WPF:在螢幕座標和 WPF 座標之間轉換

  • August 15, 2011

我知道如果電腦未使用預設 DPI 設置,WPF 座標與“真實”螢幕座標(像素座標)不同。在我的程序中,我想 (1) 找出 WPF 視窗在哪個監視器上,(2) 在同一監視器的左下角打開另一個視窗。我聽說 WPF 沒有Screen的等價物,所以我使用 WinForms 版本,如下所示,在預設的 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 中,這兩個步驟都無法正常工作,並且可能會使視窗完全脫離螢幕。

到目前為止,看起來我可以在第一部分使用Visual.PointToScreen :

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?

  1. WPF 視窗在哪個螢幕上:
private static Screen GetScreen(Window window)
{
  return Screen.FromHandle(new WindowInteropHelper(window).Handle);
}
  1. 在同一螢幕的左下角打開另一個視窗:
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;
}

引用自:https://stackoverflow.com/questions/6931333