多个显示器上的坐标错误

时间:2011-05-17 11:59:17

标签: wpf multiple-monitors

我有一个Datagrid,我想知道datacell的位置,用窗口覆盖它。
只使用一台显示器就可以正常工作,但是有多台显示器,窗户就会移位 这是代码:

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

有人在多台显示器上有定位经验吗?

编辑:
我做了以下测试:

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

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

结果:
- 单监视器:0&lt; - &gt; 30; 20 - &lt; 20&gt; 50; 100&lt; - &gt;。 130个
   ==&GT;总是相差30(可能是由标题栏引起的)
- 双监视器:0&lt; - &gt; 30; 20 - &lt; 20&gt; 55; 100&lt; - &gt;。 153个
==&GT;在0,0的差异为30.但是我越是将窗口从0移开。差异越大,但应保持不变。很奇怪!

EDIT2:
这是我的解决方案,感谢CodeNaked提示:

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;

3 个答案:

答案 0 :(得分:5)

这可能与非标准DPI设置有关,但我很确定该设置会影响所有显示器。 This blog显示了如何获得正确的位置。但代码是有效的:

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;

答案 1 :(得分:1)

您描述的行为不正确,我无法重现。 我使用以下代码创建了一个简单的窗口:

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

最后一行(=两个坐标之间的差异)永远不会改变。

答案 2 :(得分:0)

我无法重现您的体验问题。窗口客户区的左上角(由PointToScreen返回的点)始终从窗口的左上角水平移动8个像素,垂直移动30个像素。这是双显示器设置。

你应该可以从SystemParameters class计算值8和30,但是我必须承认我不确定用什么参数来得出我系统上的实际值。