C# 每个监视器的WPF ClickOnce DPI感知v2
我将设置这个问题并自己回答,这样其他人就可以轻松地搜索并找到正确的答案。我不得不用谷歌搜索数小时,并从多个来源编译最终结果 因此,问题是-如何在ClickOnce场景(特别是WPF、c)中启用每监视器v2 DPI感知?C# 每个监视器的WPF ClickOnce DPI感知v2,c#,wpf,clickonce,dpi,C#,Wpf,Clickonce,Dpi,我将设置这个问题并自己回答,这样其他人就可以轻松地搜索并找到正确的答案。我不得不用谷歌搜索数小时,并从多个来源编译最终结果 因此,问题是-如何在ClickOnce场景(特别是WPF、c)中启用每监视器v2 DPI感知? Win 10 Creators更新(1703)中添加了每监视器v2。众所周知,ClickOnce不支持app.manifest文件中声明的DPI感知功能。首先,任何想大声叫喊的人-默认情况下,每个监视器的目标.NET 4.6.2 DPI感知功能都是启用的-这根本不是真的。 在.N
Win 10 Creators更新(1703)中添加了每监视器v2。众所周知,ClickOnce不支持app.manifest文件中声明的DPI感知功能。首先,任何想大声叫喊的人-默认情况下,每个监视器的目标.NET 4.6.2 DPI感知功能都是启用的-这根本不是真的。
在.NET 4.62中默认启用的是后台的样板代码——在Windows声明代码中非常讨厌的C++钩子,以支持对每个监视器DPI的认识。 您仍然必须通过app.manifest声明支持每监视器dpi感知,但ClickOnce不支持此功能。
(请注意,早期版本的.NET将不支持每监视器dpi感知,即使使用应用程序清单,除非您) 现在回答:
[assembly:DisableDpiAwareness]
。(这将需要一个using System.Windows.Media;
语句,只需单击鼠标悬停在红色曲线上时出现的灯泡,然后添加建议的using语句)internal static class NativeMethods
{
[DllImport("user32.dll", SetLastError = true)]
internal static extern bool SetProcessDpiAwarenessContext(int dpiFlag);
[DllImport("SHCore.dll", SetLastError = true)]
internal static extern bool SetProcessDpiAwareness(PROCESS_DPI_AWARENESS awareness);
[DllImport("user32.dll")]
internal static extern bool SetProcessDPIAware();
internal enum PROCESS_DPI_AWARENESS
{
Process_DPI_Unaware = 0,
Process_System_DPI_Aware = 1,
Process_Per_Monitor_DPI_Aware = 2
}
internal enum DPI_AWARENESS_CONTEXT
{
DPI_AWARENESS_CONTEXT_UNAWARE = 16,
DPI_AWARENESS_CONTEXT_SYSTEM_AWARE = 17,
DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE = 18,
DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 = 34
}
}
protected override void OnStartup(StartupEventArgs e)
{
if (Environment.OSVersion.Version >= new Version(6, 3, 0)) // win 8.1 added support for per monitor dpi
{
if (Environment.OSVersion.Version >= new Version(10, 0, 15063)) // win 10 creators update added support for per monitor v2
{
NativeMethods.SetProcessDpiAwarenessContext((int)NativeMethods.DPI_AWARENESS_CONTEXT.DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
}
else NativeMethods.SetProcessDpiAwareness(NativeMethods.PROCESS_DPI_AWARENESS.Process_Per_Monitor_DPI_Aware);
}
else NativeMethods.SetProcessDPIAware();
base.OnStartup(e);
}
OnDpiChanged
事件和visualtreeheloper.GetDpi()
方法享受:)在应用程序中声明的DPI感知。显示.NET 4.7.2功能之一 @Marko-回答得好!但这里有一个小细节:如果您将WinForms与WPF混合,则必须添加WinForms配置。请更新你的答案,我没有足够的理由留下评论
<System.Windows.Forms.ApplicationConfigurationSection>
<add key="DpiAwareness" value="PerMonitorV2" />
</System.Windows.Forms.ApplicationConfigurationSection>
我试过了,除了应用程序内的滚动条(scrollviewer)无法缩放外,其他一切似乎都正常。你知道为什么吗?如果我通过清单声明V2支持,滚动条看起来很好,但当然部署中断。我已经验证了使用V2调用SetProcessDpiAwarenessContext是否成功。(windows 10,最新更新,目标为4.6.2)此解决方案是否适用于windows 7?它适用于windows 10 perfectlyWin 10 v1803,目标.NET 4.7.2确实适用于以下清单:
PerMonitorV2,PerMonitor,System
遗憾的是,这不适用于安装了.NET 4.7.2的服务器2008r2(也可能是Win 7),因为无法分析清单。