For anyone who comes across this problem I managed to solve it with a bit of back and forth with ChatGPT!
My App didn't like the app.manifest method so ignore that.
Adding the following code to App.xaml.cs didn't work either:
Code:
[DllImport("user32.dll")]
private static extern bool SetProcessDpiAwarenessContext(IntPtr dpiContext);
private static readonly IntPtr DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 = new IntPtr(-4);
[STAThread]
public static void Main()
{
SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
var app = new App();
app.InitializeComponent();
app.Run();
}
I had to create a Class at the root of my project in solution explorer. Called it Program.cs, with the following content:
Code:
using System.Runtime.InteropServices;
namespace Layout_Test // ? Make sure this matches your actual project namespace
{
public class Program
{
[DllImport("user32.dll")]
private static extern bool SetProcessDpiAwarenessContext(IntPtr dpiContext);
private static readonly IntPtr DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 = new IntPtr(-4);
[STAThread]
public static void Main()
{
SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
var app = new App();
app.InitializeComponent();
app.Run();
}
}
}
Then in my project's .csproj file add <StartupObject>Layout_Test.Program</StartupObject> to the "PropertyGroup" so my full .csproj file was as follows:
Code:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net9.0-windows</TargetFramework>
<RootNamespace>Layout_Test</RootNamespace>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<UseWPF>true</UseWPF>
<StartupObject>Layout_Test.Program</StartupObject>
</PropertyGroup>
</Project>
ChatGPT's summary was as follows:
Method |
Works? |
SetProcessDpiAwarenessContext() in App.xaml.cs |
? Not early enough |
Manifest with dpiAwareness |
?? Hit-or-miss on .NET SDK style |
Main() in Program.cs + DPI set before WPF starts |
? Correct and reliable |
Hope this helps someone.