Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wrong coordinates on multiple monitors

I have a Datagrid and I want to know the position of a datacell for overlaying it with a window.
It works fine with only one monitor, but with multiple monitors, the window is displaced.
Here's the code:

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

Somebody has some experience with positioning on multiple monitors?

EDIT:
I made following test:

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

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

Results:
- Single-Monitor: 0 <--> 30; 20 <--> 50; 100 <--> 130
==> Always difference of 30 (may be caused by title bar)
- Dual-Monitor: 0 <--> 30; 20 <--> 55; 100 <--> 153
==> At 0,0 difference of 30. But the more I moved the window away from 0,0. the greater becomes the difference, but should stay the same. Very strange!

EDIT2:
Here's my solution, thanks to CodeNaked for the hint:

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;
like image 422
SpeziFish Avatar asked May 17 '11 11:05

SpeziFish


People also ask

How do you change monitor 1 and 2 left and right?

Right-click on your desktop and select "Display". At the top of the resulting dialogue box, your available monitors appear as blue, numbered boxes. Each box represents a monitor. If you want the mouse to scroll left to right across your monitors, make sure monitor "1" is on the left and monitor "2" is on the right.

How do I fix scaling on my second monitor?

Select Display > Change the size of text, apps, and other items, and then adjust the slider for each monitor. Right-click the application, select Properties, select the Compatibility tab, and then select the Disable display scaling on high DPI settings check box.


2 Answers

This may have to do with a non-standard DPI setting, but I'm pretty sure that setting affects all monitors. This blog shows how to get the correct position. But the code is effectively:

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;
like image 106
CodeNaked Avatar answered Sep 25 '22 19:09

CodeNaked


The behavior you described is not correct and I can't reproduce it. I created a simple Window with the following code:

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

The last line (= the difference between the two coordinates) never changes.

like image 34
Daniel Hilgarth Avatar answered Sep 25 '22 19:09

Daniel Hilgarth