混合 WPF 和 winforms 项目 DPI 意识
Mixed WPF and winforms project DPI awareness
我有一个同时使用 winforms 和 WPF 的 C# 程序,我正在努力让它在高 DPI 环境中工作。
目前,如果我从解决方案中删除所有 WPF 项目并 运行 它,它会很好地缩放,但是一旦我添加任何 wpf 回到(功能所必需的)缩放失败并且 UI变得无法使用。
这似乎与之前的 SO 问题完全相同:DPI Scaling in .Net 3.5 in Mixed WinForms and WPF Application and Problems getting WinForms to scale correctly with DPI
我听从了关于这些问题的建议,并尝试添加清单文件和提供的 dpi 感知代码。
我还将项目升级到 .net framework 4.6.1(从 4.0)并包含 app.config 设置:<add key="EnableWindowsFormsHighDpiAutoResizing" value="true" />
这确实影响了程序的主程序 shell(因此主程序 window 打开时最大化并显示正常)但是,当我从主 window 输入任何 winforms 子表单或插件时,缩放失败。
当我输入任何 WPF 子窗体或插件,或 return 到主屏幕时,它们会正确呈现。只有 winforms 功能无法正确缩放。
有没有人知道如何混合 winforms/WPF 项目以在高 DPI 下正确缩放?
提前致谢
当 WPF 加载到项目中时,它会将进程提升为系统 DPI 感知。为了解决这个问题,首先:
1) 在您的条目程序集中的命名空间声明上方设置 [assembly: DisableDpiAwareness] 属性
2) 您可以在您的项目中添加一个 app.manifest 文件并添加以下内容:
<asmv3:windowsSettings
xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>true/PM</dpiAware>
</asmv3:windowsSettings>
这应该会以正确的目标 DPI 呈现您的 WinForms 和 WPF 内容。 (但是,如果你有一个具有不同 DPI 的多显示器设置,这将无法扩展)。
我的同事终于解决了这个问题。由于 none 配置设置等适用于此项目,我们尝试删除 winforms shell 并将其替换为 WPF shell。在 WPF 中重新编写主要 shell 项目后,所有 'plugins' 都出现在正确的 DPI 缩放中。
考虑到它涉及重写现有代码,这不是我所知道的最佳解决方案,但这是为我们解决问题的唯一办法。
非常感谢@rohit21agrawal 的回答!
我有一个非常相似的复杂 Win Forms 解决方案,每当我在 WeifenLuo 的 DockPanelSuite 中打开一个停靠的窗体时,该窗体会调整大小并弄乱整个 GUI。
现在,在尝试了几年不同的方法(并且 none 有效)之后,你救了我的命!
除了您对其他想知道如何完成您的解决方案的开发人员的回答之外:
- a)(我的项目以 .NET Framework 4.7.2 为目标)
- b)(我所有的表格都设置为AutoScaleMode = Font)
- 在您的 WinForms 项目中,添加一个 对 WindowsBase 的引用(应该是程序集列表中的倒数第三个条目)
- 将“
[assembly: System.Windows.Media.DisableDpiAwareness]
”添加到您的 AssemblyInfo.cs
- 添加“
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>true/PM</dpiAware>
</windowsSettings>
</application>
" 到 app.manifest 文件
的父级“<assembly>…</assembly>
”部分
就我而言,这就像一个魅力:-)
最终我能够在不同的显示器之间移动表单(一个 4K 175% 和另一个全高清 125% 字体比例)并且它立即 redraws/re-renders 所有控件!
再次感谢您!
线数
如果因为您是 WinForms 应用程序而不是 WPF 应用程序而没有清单文件,则必须通过 AssemblyInfo.cs 进行更改。因为方向相反,您必须禁用 DPI 感知才能使世界同步,而不是像上述 WPF 方法那样启用它。
在 AssemblyInfo.cs 中,添加以下行。
[assembly: System.Windows.Media.DisableDpiAwareness]
我的问题被标记为与此重复,但不是真正的重复,因为我有一个使用 WPF 组件的 WinForms 应用程序,而不是相反。我正在为像我这样因为错误原因被引导到这里的人添加这个答案。
我有一个同时使用 winforms 和 WPF 的 C# 程序,我正在努力让它在高 DPI 环境中工作。 目前,如果我从解决方案中删除所有 WPF 项目并 运行 它,它会很好地缩放,但是一旦我添加任何 wpf 回到(功能所必需的)缩放失败并且 UI变得无法使用。
这似乎与之前的 SO 问题完全相同:DPI Scaling in .Net 3.5 in Mixed WinForms and WPF Application and Problems getting WinForms to scale correctly with DPI
我听从了关于这些问题的建议,并尝试添加清单文件和提供的 dpi 感知代码。
我还将项目升级到 .net framework 4.6.1(从 4.0)并包含 app.config 设置:<add key="EnableWindowsFormsHighDpiAutoResizing" value="true" />
这确实影响了程序的主程序 shell(因此主程序 window 打开时最大化并显示正常)但是,当我从主 window 输入任何 winforms 子表单或插件时,缩放失败。
当我输入任何 WPF 子窗体或插件,或 return 到主屏幕时,它们会正确呈现。只有 winforms 功能无法正确缩放。
有没有人知道如何混合 winforms/WPF 项目以在高 DPI 下正确缩放?
提前致谢
当 WPF 加载到项目中时,它会将进程提升为系统 DPI 感知。为了解决这个问题,首先: 1) 在您的条目程序集中的命名空间声明上方设置 [assembly: DisableDpiAwareness] 属性 2) 您可以在您的项目中添加一个 app.manifest 文件并添加以下内容:
<asmv3:windowsSettings
xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>true/PM</dpiAware>
</asmv3:windowsSettings>
这应该会以正确的目标 DPI 呈现您的 WinForms 和 WPF 内容。 (但是,如果你有一个具有不同 DPI 的多显示器设置,这将无法扩展)。
我的同事终于解决了这个问题。由于 none 配置设置等适用于此项目,我们尝试删除 winforms shell 并将其替换为 WPF shell。在 WPF 中重新编写主要 shell 项目后,所有 'plugins' 都出现在正确的 DPI 缩放中。
考虑到它涉及重写现有代码,这不是我所知道的最佳解决方案,但这是为我们解决问题的唯一办法。
非常感谢@rohit21agrawal 的回答!
我有一个非常相似的复杂 Win Forms 解决方案,每当我在 WeifenLuo 的 DockPanelSuite 中打开一个停靠的窗体时,该窗体会调整大小并弄乱整个 GUI。
现在,在尝试了几年不同的方法(并且 none 有效)之后,你救了我的命!
除了您对其他想知道如何完成您的解决方案的开发人员的回答之外:
- a)(我的项目以 .NET Framework 4.7.2 为目标)
- b)(我所有的表格都设置为AutoScaleMode = Font)
- 在您的 WinForms 项目中,添加一个 对 WindowsBase 的引用(应该是程序集列表中的倒数第三个条目)
- 将“
[assembly: System.Windows.Media.DisableDpiAwareness]
”添加到您的 AssemblyInfo.cs - 添加“
<application xmlns="urn:schemas-microsoft-com:asm.v3"> <windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings"> <dpiAware>true/PM</dpiAware> </windowsSettings> </application>
" 到 app.manifest 文件
的父级“<assembly>…</assembly>
”部分
就我而言,这就像一个魅力:-) 最终我能够在不同的显示器之间移动表单(一个 4K 175% 和另一个全高清 125% 字体比例)并且它立即 redraws/re-renders 所有控件!
再次感谢您! 线数
如果因为您是 WinForms 应用程序而不是 WPF 应用程序而没有清单文件,则必须通过 AssemblyInfo.cs 进行更改。因为方向相反,您必须禁用 DPI 感知才能使世界同步,而不是像上述 WPF 方法那样启用它。
在 AssemblyInfo.cs 中,添加以下行。
[assembly: System.Windows.Media.DisableDpiAwareness]
我的问题被标记为与此重复,但不是真正的重复,因为我有一个使用 WPF 组件的 WinForms 应用程序,而不是相反。我正在为像我这样因为错误原因被引导到这里的人添加这个答案。