当前位置: 首页 > article >正文

【沧海拾昧】C# .NET8 WinForms程序在主显示器125%/150%缩放下尺寸显示异常的解决办法

#C0106


沧海茫茫千钟粟,且拾吾昧一微尘

——《沧海拾昧集》@CuPhoenix


【阅前敬告】
沧海拾昧集仅做个人学习笔记之用,所述内容不专业不严谨不成体系
【如有问题必是本集记录有谬,切勿深究】

问题

    使用 C#(.NET8)进行 WinForms 程序开发时,如果主显示器的缩放比例不为100%,会出现窗体和控件显示尺寸异常的问题,网上通常的方案是在 Program.cs 中加入 SetProcessDPIAware(); 函数,但该函数可能对 .NET8 的 WinForms 程序无效。

[STAThread]
    static void Main() {
        if (Environment.OSVersion.Version.Major >= 6) SetProcessDPIAware();
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());             // Edit as needed
    }

    [System.Runtime.InteropServices.DllImport("user32.dll")]
    private static extern bool SetProcessDPIAware();

解决

    通过参考 .NET8 的官方文档和 Git 手册,在 项目名.csproj 文件中(可以搜索 <Project Sdk = “Microsoft.NET.Sdk”> 找到该文件),将 <PropertyGrop></Property>中的内容修改为:

<PropertyGroup>
  <OutputType>WinExe</OutputType>
  <TargetFramework>net8.0-windows</TargetFramework>
  <Nullable>enable</Nullable>
  <UseWindowsForms>true</UseWindowsForms>
  <ImplicitUsings>enable</ImplicitUsings>
  <ApplicationHighDpiMode>DpiUnawareGdiScaled</ApplicationHighDpiMode>
  <ForceDesignerDpiUnaware>true</ForceDesignerDpiUnaware>
</PropertyGroup>

说明

    资料1:WinForms GitHub 手册 - Designer HighDpi mode 中提到:

Issues
    The Winforms designer, when operating in SystemAware/PermonitorV2 mode, serializes layout metrics into the > > source file based on the Dpi setting of the current display device on which it is being rendered. This may lead to two kinds of problems.
    WinForms applications developed on a machine with DPI settings different from the machine where they are> > > executed may encounter layout inconsistencies.
Solution

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
   <OutputType>WinExe</OutputType>
   <TargetFramework>net7.0-windows</TargetFramework>
   <Nullable>enable</Nullable>
   <UseWindowsForms>true</UseWindowsForms>
    <ImplicitUsings>enable</ImplicitUsings>
    <ApplicationHighDpiMode>SystemAware</ApplicationHighDpiMode>
    <ForceDesignerDpiUnaware>true</ForceDesignerDpiUnaware>
  </PropertyGroup>

    但该解决方案中设置的 <ApplicationHighDpiMode> 属性值是错误的,SystemAware 将查询主监视器的 DPI 一次,并将此值用于所有监视器上的应用程序,因此不能解决问题。

    资料2:.NET8 Learn - ApplicationHighDpiMode,通过微软官方的学习手册,查阅该属性值的取值。ApplicationHighDpiMode 可设置为 HighDpiMode 枚举值之一:

说明
DpiUnaware应用程序窗口不会缩放 DPI 更改,并且始终假定比例系数为 100%。
DpiUnawareGdiScaled类似于 DpiUnaware,但提高了基于 GDI/GDI+ 的内容的质量。
PerMonitor此窗口会在创建 DPI 时对其进行检查,并在 DPI 更改时调整缩放比例。
PerMonitorV2类似于 PerMonitor,但启用了子窗口 DPI 更改通知、comctl32 控件的改进缩放和对话框缩放。
SystemAware如果未指定,则为默认值。窗口查询主监视器的 DPI 一次,并将此值用于所有监视器上的应用程序。

选择合适的取值(如 DpiUnawareGdiScaled)即可。

敬谢诸君。



http://www.kler.cn/news/322007.html

相关文章:

  • 如何使用ssm实现基于JavaWeb的个人健康信息管理系统
  • 学生党头戴式蓝牙耳机怎么选?平价学生党头戴式蓝牙耳机排行推荐
  • 侧边菜单的展开和折叠
  • 振动韧性与智能的双翼,让数智金融飞向未来之屿
  • uniapp监听滚动实现顶部透明度变化
  • uniapp js怎么根据map需要显示的点位,计算自适应的缩放scale
  • django drf to_internal_value
  • YOLOv8+注意力机制+PyQt5玉米病害检测系统完整资源集合
  • 微信小程序-WebSocket
  • git diff 命令
  • 【逐行注释】MATLAB的程序,对比EKF(扩展卡尔曼滤波)和PF(粒子滤波)的滤波效果,附下载链接
  • ruoyi源码解析学习 - 微服务版 - ruoyi-gateway
  • 【人工智能】多模态AI:如何通过融合文本、图像与音频重塑智能系统未来
  • Qt系统相关——QFile和QFileInfo
  • 笔记整理—内核!启动!—linux应用编程、网络编程部分(5)系统时间与信息
  • Django 依赖库管理
  • 【计网】从零开始掌握序列化 --- 基础知识储备与程序重构
  • Ubuntu24.04下安装Budgie桌面的注意事项
  • 【C++掌中宝】深入理解函数重载:概念、规则与应用
  • Map和Set,TreeMap和TreeSet,HashMap和HashSet
  • Docker安装和配置MySQL 5.7的完整指南
  • 【Unity与数据库01】开发者如何选择数据库
  • 深度学习:(五)初识神经网络
  • Unity2022.3.x各个版本bug集合及推荐稳定版本
  • 使用jQuery处理Ajax
  • kotlin——设计模式之责任链模式
  • 数据结构之二叉树(1)
  • 本地生活服务项目揭秘!谁搭建的本地生活服务商作业系统收益效果好?
  • 使用ELK Stack进行日志管理和分析:从入门到精通
  • JDK7和JDK8中的HashMap有什么区别?