Неправильные координаты на нескольких мониторах - PullRequest
7 голосов
/ 17 мая 2011

У меня есть Datagrid, и я хочу знать положение ячейки данных для наложения ее на окно.
Он отлично работает только с одним монитором, но с несколькими мониторами окно смещено.
Вот код:

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

У кого-нибудь есть опыт позиционирования на нескольких мониторах?

EDIT:
Я сделал следующий тест:

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 <-> 30; 20 <-> 50; 100 <-> 130
==> Всегда разница 30 (может быть вызвана строкой заголовка)
- Двойной монитор: 0 <-> 30; 20 <-> 55; 100 <-> 153
==> При 0,0 разности 30. Но чем больше я сдвинул окно от 0,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 ]

5 голосов
/ 17 мая 2011

Возможно, это связано с нестандартной настройкой DPI, но я уверен, что эта настройка влияет на все мониторы. Этот блог показывает, как получить правильную позицию. Но код эффективен:

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 голос
/ 17 мая 2011

Вы описали неправильное поведение, и я не могу его воспроизвести. Я создал простое окно со следующим кодом:

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

Последняя строка (= разница между двумя координатами) никогда не меняется.

0 голосов
/ 17 мая 2011

Я не могу воспроизвести проблему вашего опыта.Верхний левый угол клиентской области окна (точка, возвращаемая PointToScreen) всегда переводится на 8 пикселей по горизонтали и 30 пикселей по вертикали от верхнего левого угла окна.Это на установке с двумя мониторами.

Вы должны быть в состоянии вычислить значения 8 и 30 из SystemParameters класса , однако я должен признать, что не уверенкакие параметры использовать для получения фактических значений в моей системе.

...