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;
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.
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.
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;
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With