.NET 4.5.2环境下调用DataGridView的Update/Refresh后窗体分辨率异常
解决方案
- 开启应用高DPI感知适配
.NET 4.5.2默认未启用系统高DPI适配,跨进程拖放操作会触发系统临时修改进程DPI感知模式,进而引发窗体整体缩放错乱。在项目的app.manifest文件中添加如下配置,显式声明DPI感知能力:<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> <!-- 原有配置保留,新增以下节点 --> <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> <application> <!-- 兼容Windows 10/11 --> <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" /> </application> </compatibility> <application xmlns="urn:schemas-microsoft-com:asm.v3"> <windowsSettings> <!-- 开启Per-Monitor DPI感知 --> <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/PM</dpiAware> </windowsSettings> </application> </assembly> - 移除冗余重绘逻辑
Refresh()方法内部已经包含了控件无效化、触发重绘、执行更新的完整流程,无需额外调用Update(),原有代码可简化为:this.dataGridView.BeginInvoke(new Action(() => this.dataGridView.Refresh())); - 固定窗体缩放参数
在窗体的Load事件中显式指定缩放模式和基准参数,避免拖放操作意外修改缩放配置:private void MainForm_Load(object sender, EventArgs e) { this.AutoScaleMode = AutoScaleMode.Dpi; // 固定设计时的96DPI基准,避免运行时被自动修改 this.AutoScaleDimensions = new SizeF(96F, 96F); } - 兜底强制设置进程DPI感知
若上述配置仍未解决问题,可在程序入口Program.cs的Main方法最开头调用系统API固定进程DPI感知等级:using System.Runtime.InteropServices; static class Program { [DllImport("user32.dll", SetLastError = true)] private static extern bool SetProcessDPIAware(); [STAThread] static void Main() { // Vista及以上系统提前设置DPI感知 if (Environment.OSVersion.Version.Major >= 6) { SetProcessDPIAware(); } Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new MainForm()); } }
内容的提问来源于stack exchange,提问作者Marcel Piquet
相关产品推荐
相关产品推荐

