2011-08-03 3 views
10

Je comprends que les coordonnées WPF sont différentes des coordonnées «réelles» de l'écran (coordonnées de pixels) si l'ordinateur n'utilise pas le réglage DPI par défaut. Dans mon programme, je veux (1) comprendre quel moniteur est une fenêtre WPF et (2) ouvrir une autre fenêtre dans le coin inférieur gauche du même moniteur. J'ai entendu il n'y a pas d'équivalent de Screen pour WPF donc j'utiliser la version WinForms, comme suit, qui fonctionne très bien à la valeur par défaut 96 DPI:WPF: Conversion entre les coordonnées de l'écran et les coordonnées 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; 
} 

Mais à d'autres DPIs, les deux étapes fonctionnent correctement, et peuvent mettre la fenêtre complètement hors écran.

Jusqu'à présent, il semble que je peux utiliser Visual.PointToScreen pour la première partie:

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; 

Je ne suis pas sûr que ce soit tout à fait raison, car il ne peut pas tenir compte des frontières correctement. Mais la deuxième partie est plus importante. Comment puis-je convertir le rectangle d'écran "scr" dans l'espace WPF, afin de régler correctement les paramètres Left et Top?

+2

Non sûr de la prise en charge de plusieurs moniteurs, mais vous pouvez positionner correctement votre fenêtre o n l'écran principal utilisant seulement WPF (qui est DPI) sans aucune référence à Windows Forms (qui n'est pas sensible au DPI) en utilisant la classe SystemParameters. Les propriétés pertinentes s'ajustent automatiquement aux différents paramètres DPI. Exemple: window.Top = SystemParameters.FullPrimaryScreenHeight - (window.ActualHeight - SystemParameters.WindowCaptionHeight); // Fonctionne sur Vista et Windows 7, ne sait pas à propos de XP. –

Répondre

25
  1. Quel écran une fenêtre WPF est sur:

    private static Screen GetScreen(Window window) 
    { 
        return Screen.FromHandle(new WindowInteropHelper(window).Handle); 
    } 
    
  2. Ouvrir une autre fenêtre dans le coin inférieur gauche du même écran:

    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

Ajout de la méthode d'assistance RealPixelsToWpf(). – Qwertie

2

Est-ce que cela fonctionne si vous le placez dans le code-behind pour votre fenêtre?

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