You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# WinForms固定对话框高DPI缩放时被裁剪的适配方法咨询

问题描述

我有一个固定尺寸的对话框,特定情况下右侧会被隐藏,我在_Load事件中处理其尺寸:

_Mru = Crud.MruTableMethods.GetMruTables();
if (_Mru == null)
{
    this.Size = new Size(275, 261);
}
else
{
    this.Size = new Size(512, 261);
}

若在设计器中定义尺寸则显示正常,但Windows 11用户将「缩放与布局」设置为100%以上时,对话框会被相应比例裁剪;切换回100%缩放则显示正常。

请问是否有方法可让对话框尺寸动态适配系统缩放比例?

环境说明:.NET Framework 4.8,未启用Autosize(固定对话框),暂未了解DPI Awareness,将进一步查看。


解决方案

1. 启用DPI感知(DPI Awareness)

.NET Framework 4.8原生支持DPI感知,先让应用正确识别系统缩放比例,避免Windows自动拉伸导致的裁剪问题。

方式一:通过应用程序清单配置

打开项目的app.manifest文件,找到并取消注释以下代码段,修改为支持每显示器DPI感知:

<application xmlns="urn:schemas-microsoft-com:asm.v3">
  <windowsSettings>
    <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/PM</dpiAware>
  </windowsSettings>
</application>

true/PM表示支持每显示器DPI感知,能适配不同屏幕的缩放比例;若仅需适配系统级缩放,可改为true。

方式二:通过代码设置(适合无法修改清单的场景)

在应用启动入口(如Program.cs的Main方法)添加以下代码:

using System.Windows.Forms;
using System.Runtime.InteropServices;

[DllImport("user32.dll", SetLastError = true)]
private static extern bool SetProcessDpiAwarenessContext(int dpiFlag);

private const int DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 = 3;

static void Main()
{
    // 启用Per-Monitor V2 DPI感知
    SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
    
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new YourDialogForm());
}

2. 基于DPI缩放计算对话框尺寸

启用DPI感知后,需根据当前屏幕的DPI比例动态计算尺寸,替代固定像素值:

private void YourDialog_Load(object sender, EventArgs e)
{
    // 获取当前窗体的DPI缩放比例(96为100%缩放的基准DPI)
    float dpiScale = this.DeviceDpi / 96f;
    
    _Mru = Crud.MruTableMethods.GetMruTables();
    if (_Mru == null)
    {
        int scaledWidth = (int)(275 * dpiScale);
        int scaledHeight = (int)(261 * dpiScale);
        this.Size = new Size(scaledWidth, scaledHeight);
    }
    else
    {
        int scaledWidth = (int)(512 * dpiScale);
        int scaledHeight = (int)(261 * dpiScale);
        this.Size = new Size(scaledWidth, scaledHeight);
    }
}

3. 处理运行时DPI变化(可选)

若需支持用户在程序运行时调整缩放比例,可订阅窗体的DpiChanged事件,实时重新计算尺寸:

private void YourDialog_DpiChanged(object sender, DpiChangedEventArgs e)
{
    float newDpiScale = e.DeviceDpiNew / 96f;
    if (_Mru == null)
    {
        this.Size = new Size((int)(275 * newDpiScale), (int)(261 * newDpiScale));
    }
    else
    {
        this.Size = new Size((int)(512 * newDpiScale), (int)(261 * newDpiScale));
    }
}

注意:启用Per-Monitor DPI感知后,所有固定尺寸的控件都需要同步按比例调整,确保整体布局适配缩放。

内容的提问来源于stack exchange,提问作者Hambone

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 07:20:07