Have you tried Per Monitor DPI ?
PointToScreen with Scaling Problem
I've noticed this issue when working on a secondary Monitor. Here's the two Monitor with different resolution and Scaling:
When I launch the App in Monitor 1, the BusyWindow
is positioned correctly:
If I hit Windows + P
and select Extend
, and move the app to Monitor 2, it also works fine on the Monitor 2:
If I hit Windows + P
and select Second screen only
, run the app and hit refresh buttons, the BusyWindow
opens in wrong position or goes off screen:
How to fix this problem?
EDIT
----
Looks like the problem is with scaling! I didn't have App.config
and app.manifest
files in my project, I have added those 2 with following content in App.config
:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<runtime>
<AppContextSwitchOverrides value ="Switch.System.Windows.DoNotScaleForDpiChanges=false"/>
</runtime>
</configuration>
and app.manifest
:
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
</requestedPrivileges>
</security>
</trustInfo>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
</application>
</compatibility>
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitor</dpiAwareness>
<longPathAware xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">true</longPathAware>
</windowsSettings>
</application>
</assembly>
and my Windows 10 is Version 1809 (OS Build 17763.1999), with all those in project and 125% scaling in Monitor 1, this is what it does:
2 answers
Sort by: Most helpful
-
-
Emon Haque 3,176 Reputation points
2021-07-02T10:38:31.193+00:00 Tried with the following change in one of my views and it works:
void refreshCommand() { if (BusyWindow.IsOpened) return; var dpi = VisualTreeHelper.GetDpi(this); var position = PointToScreen(new Point(0, 0)); position.X /= dpi.DpiScaleX; position.Y /= dpi.DpiScaleY; position.X += Constants.CardMargin.Left; position.Y += Constants.CardMargin.Top; var width = ActualWidth - Constants.CardMargin.Left - Constants.CardMargin.Right; var height = ActualHeight - Constants.CardMargin.Top - Constants.CardMargin.Bottom; BusyWindow.Activate(position.X, position.Y, width, height, "Reloading ..."); viewModel.Refresh.Invoke(); BusyWindow.Terminate(); }
So I have to divide x,y of PointToScreen by dpiscale, and with this I don't need
App.Config/app.manifest
. Not bad! Is there any better way?EDIT
----
BUT this approach isn't pixel perfect! For example, with 100% and 125% scaling on these two Monitors:I see white stripes clearly on right in 2 leftmost views and the view in the middle on Monitor with 100% scaling. Those stripes shift to the left in 2 rightmost views :
and on 125%, those stipes become subtle:
Is it possible to make it pixel perfect?
Updated the RentManager without XAML ... in GitHub, you can download and test. Relevant code is in
void refreshCommand()
method in .cs files ofViews\Home
folder.