2011-05-17 11 views
6

Tengo una cuadrícula de datos y quiero saber la posición de una celda de datos para superponerla con una ventana.
Funciona bien con solo un monitor, pero con varios monitores, la ventana se desplaza.
Aquí está el código:Coordenadas incorrectas en monitores múltiples

Point point = cell.PointToScreen(new Point(0, 0)); 
... 
Window myWindow = new Window(); 
myWindow.Top = point.Y; 
myWindow.Left = point.X; 

Alguien tiene alguna experiencia con el posicionamiento en varios monitores?

EDIT:
que hice siguiente prueba:

public MyWindow() 
{ 
    ... 
    this.LocationChanged += MyWindow_LocationChanged; 
} 

void MyWindow_LocationChanged(object sender, EventArgs e) 
{ 
    Console.WriteLine(this.Top + " <--> " + this.PointToScreen(new Point(0, 0)).Y); 
} 

Resultados:
- Single-Monitor: 0 < -> 30; 20 < -> 50; 100 < -> 130
==> Siempre diferencia de 30 (puede deberse a la barra de título)
- Dual-Monitor: 0 < -> 30; 20 < -> 55; 100 < -> 153
==> En 0,0 diferencia de 30. Pero cuanto más moví la ventana de 0,0. cuanto mayor se convierte en la diferencia, pero debe permanecer igual. ¡Muy extraño!

Edit2:
aquí está mi solución, gracias a CodeNaked por la pista:

Point point = cell.PointToScreen(new Point(0, 0)); 
... 
Window myWindow = new Window(); 
PresentationSource source = PresentationSource.FromVisual(this); 
myWindow.Top = point.Y/source.CompositionTarget.TransformToDevice.M22; 
myWindow.Left = point.X/source.CompositionTarget.TransformToDevice.M11; 
+0

Por favor, publique los valores que obtenga y los valores que espera. –

+0

No sé lo que tengo que hacer salvo. El PointToScreen y el punto de la ventana son los mismos, por lo que el error ya está en PointToScreen-Method. – SpeziFish

+0

Agregó algunos resultados de prueba a la pregunta. – SpeziFish

Respuesta

5

Esto puede tener que ver con una configuración de PPP no estándar, pero estoy bastante seguro de que la configuración afecta a todos los monitores. This blog muestra cómo obtener la posición correcta. Pero el código es efectivamente:

PresentationSource source = PresentationSource.FromVisual(control); 

double dpiX = 96.0 * source.CompositionTarget.TransformToDevice.M11; 
double dpiY = 96.0 * source.CompositionTarget.TransformToDevice.M22; 

window.Left = point.X * 96.0/dpiX; 
window.Top = point.Y * 96.0/dpiY; 
+0

Genial, funciona, gracias. Pero en mi caso, incluso funciona sin el parámetro dpi (96.0), ver edición en mi pregunta. – SpeziFish

0

Soy incapaz de reproducir el problema de su experiencia. La esquina superior izquierda del área del cliente de la ventana (el punto devuelto por PointToScreen) siempre se traduce 8 píxeles horizontalmente y 30 píxeles verticalmente desde la esquina superior izquierda de la ventana. Esto está en una configuración de dos monitores.

Debe poder calcular los valores 8 y 30 desde SystemParameters class; sin embargo, debo admitir que no estoy seguro exactamente qué parámetros usar para llegar a los valores reales en mi sistema.

1

El comportamiento que ha descrito no es el correcto y no puedo reproducirlo. creé una simple ventana con el siguiente código:

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
     LocationChanged += (s, e) => 
      { 
       var screen = PointToScreen(new Point(0, 0)); 
       var window = new Point(Left, Top); 
       var diff = screen - window; 
       textbox.Text = window.ToString() + Environment.NewLine + 
           screen.ToString() + Environment.NewLine + diff; 
      }; 
    } 
} 

La última línea (= la diferencia entre las dos coordenadas) nunca cambia.

+0

Lo mismo con su ejemplo, la diferencia se vuelve cada vez mayor al alejarse de 0,0 ... – SpeziFish

+0

Lo probé en un sistema de doble pantalla y moví la ventana en ambos monitores ...diff es siempre constante. ¿Hay algo especial con tu configuración? –

+0

Comprobaré esto mañana. Gracias por su ayuda hasta ahora. – SpeziFish

Cuestiones relacionadas