WPF SkiaSharp Canvas Click Положение мыши

Примечание. Это приложение C# SkiaSharp WPF.

Когда я перерисовываю свой SKCanvas (который является полной шириной моего приложения), я записываю ширину и высоту. Пока не обращайте внимания на высоту. На мониторе 4K ширина записывается правильно 3840 пикселей (при максимальном увеличении).

Когда я нажимаю крайний левый край холста, записанная позиция мыши X почти равна нулю, как и ожидалось.

Однако, когда я нажимаю в крайнем правом углу холста, в качестве позиции X указывается 2552, а не что-то около 3840, как я ожидал?

Это код, который я использую для получения положения мыши при нажатии.

private void MyCanvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    var pixelPosition = e.GetPosition(sender as SKElement);
    // ...
}

и мой XAML:

<skia:SKElement
    Name="MyCanvas"
    PaintSurface="MyCanvas_PaintSurface"
    MouseLeftButtonDown="MyCanvas_MouseLeftButtonDown"
    />

Я также проверил ширину/высоту в событии SizeChanged для MyCanvas, и оно также НЕ сообщает 3840, оно сообщает 2552 как ширину?

Любые идеи, почему сообщаемая ширина составляет 2552, а фактическая ширина составляет 3840?


person Rob L    schedule 02.09.2020    source источник
comment
Похоже, монитор настроен на масштаб 150%.   -  person Leandro    schedule 02.09.2020
comment
Ты прав. Теперь мне нужно решить, как найти это в моем приложении.   -  person Rob L    schedule 02.09.2020


Ответы (1)


Как отметил @Leandro, ваше масштабирование DPI составляет 150%. Вы можете получить масштаб DPI в .NET Framework ›= 4.6.2 и .NET Core ›= 3.0 с помощью GetDpi метод VisualTreeHelper. Он возвращает DpiScale. структура, которая содержит масштабные коэффициенты горизонтального и вертикального DPI.

private void MyCanvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
   var mainWindow = Application.Current.MainWindow;
   var dpiScale = VisualTreeHelper.GetDpi(mainWindow);

   var dpiScaleX = dpiScale.DpiScaleX;
   var dpiScaleY = dpiScale.DpiScaleY;

   var pixelPosition = e.GetPosition(sender as Canvas);
   var scaledPixelPosition = new System.Windows.Point(pixelPosition.X * dpiScaleX, pixelPosition.Y * dpiScaleY);

   // ...your code.
}

Если вы работаете с более ранней версией фреймворка без GetDpi, вы можете использовать это.

var mainWindow = Application.Current.MainWindow;

Matrix m = PresentationSource.FromVisual(mainWindow).CompositionTarget.TransformToDevice;
var dpiScaleX = m.M11;
var dpiScaleY = m.M22;
person thatguy    schedule 02.09.2020