Reputation: 2372
Note: This is a C# SkiaSharp WPF application.
When I repaint my SKCanvas
(which is the full width of my app), I record the width and height. Ignore height for now. On a 4K monitor the width is recorded correctly 3840 pixels (when maximised).
When I click on the canvas far left, the mouse X position recorded is almost zero as expected.
However, when I click on the far right of the canvas 2552 is given as the X position, not something near 3840 as I expected?
This is the code I use to get the mouse position when it is clicked.
private void MyCanvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var pixelPosition = e.GetPosition(sender as SKElement);
// ...
}
and my XAML:
<skia:SKElement
Name="MyCanvas"
PaintSurface="MyCanvas_PaintSurface"
MouseLeftButtonDown="MyCanvas_MouseLeftButtonDown"
/>
I also checked the width/height in the SizeChanged
event of MyCanvas
and that does NOT report 3840 either, it reports 2552 as the width?
Any ideas why the reported width is 2552 whereas the actual width is 3840?
Upvotes: 0
Views: 1516
Reputation: 22089
As @Leandro pointed out your DPI scaling is 150%. You can get the DPI scale in .NET Framework >= 4.6.2 and .NET Core >= 3.0 with the GetDpi
method of VisualTreeHelper
. It returns a DpiScale
struct that contains the scale horizontal and vertical DPI scale factors.
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.
}
If you are working with a lower version of a framework without GetDpi
, you can use this instead.
var mainWindow = Application.Current.MainWindow;
Matrix m = PresentationSource.FromVisual(mainWindow).CompositionTarget.TransformToDevice;
var dpiScaleX = m.M11;
var dpiScaleY = m.M22;
Upvotes: 1