2011-08-03 259 views
10

我知道如果計算機沒有使用默認的DPI設置,那麼WPF座標與「真實」屏幕座標(像素座標)不同。在我的程序中,我想(1)找出哪個監視器打開了一個WPF窗口,並(2)打開同一個監視器左下角的另一個窗口。我聽說有沒有Screen爲WPF,所以我使用的WinForms版本相當於如下,這在默認的96 DPI工作正常:WPF:在屏幕座標和WPF座標之間轉換

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空間,以便正確設置左側和頂部?

+2

不確定有多個顯示器支持,但你可以正確定位你的窗口o主屏幕僅使用WPF(即DPI可識別),而不使用SystemParameters類引用Windows窗體(不支持DPI)。相關屬性會自動調整爲不同的DPI設置。例如:window.Top = SystemParameters.FullPrimaryScreenHeight - (window.ActualHeight - SystemParameters.WindowCaptionHeight); //適用於Vista和Windows 7,不知道XP。 –

回答

25
  1. 哪個屏幕WPF窗口是:

    private static Screen GetScreen(Window window) 
    { 
        return Screen.FromHandle(new WindowInteropHelper(window).Handle); 
    } 
    
  2. 公開賽在同一屏幕的左下角另一個窗口:

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

添加了RealPixelsToWpf()輔助方法。 – Qwertie

2

如果你把它放在窗口的代碼隱藏中,這是否工作?

protected override void OnContentRendered(System.EventArgs e) 
{ 
    base.OnContentRendered(e); 
    MoveToLowerRightCorner(); 
} 

private void MoveToLowerRightCorner() 
{ 
    var workingArea = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea; 
    var transform = PresentationSource.FromVisual(this).CompositionTarget.TransformFromDevice; 
    var corner = transform.Transform(new Point(workingArea.Right, workingArea.Bottom)); 
    this.Left = corner.X - this.ActualWidth; 
    this.Top = corner.Y - this.ActualHeight; 
} 
相關問題