Dot-Net
WPF:在螢幕座標和 WPF 座標之間轉換
我知道如果電腦未使用預設 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?
- WPF 視窗在哪個螢幕上:
private static Screen GetScreen(Window window) { return Screen.FromHandle(new WindowInteropHelper(window).Handle); }
- 在同一螢幕的左下角打開另一個視窗:
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; }