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

Windows Forms绘制矩形Y坐标偏移问题求助

解决System.Drawing绘制矩形Y坐标偏移(按比例缩放)的问题

问题根因

你遇到的Y坐标按比例偏移,大概率是Graphics对象的坐标单位设置错误,或者高DPI环境下的坐标未做适配:

  • 如果Graphics.PageUnit被设为GraphicsUnit.Point,由于1Point对应1/72英寸,而屏幕默认DPI是96,Y轴会被自动缩放为96/72≈1.333倍,导致偏移随Y值增大而更明显。
  • 高DPI环境下,鼠标事件的坐标是经过系统缩放的客户端坐标,但如果Graphics对象未同步DPI设置,会出现坐标不匹配。

解决方案

1. 强制设置Graphics的坐标单位为像素

在绘制前,明确指定Graphics.PageUnit为Pixel,避免单位转换导致的缩放:

private void Form1_Paint(object sender, PaintEventArgs e)
{
    // 确保使用像素作为坐标单位
    e.Graphics.PageUnit = GraphicsUnit.Pixel;
    e.Graphics.FillRectangle(Brushes.Black, new Rectangle(mouseX, mouseY, 10, 10));
}

2. 适配高DPI环境(针对.NET Framework项目)

如果你的项目是.NET Framework,需要先在app.manifest中开启Per-Monitor DPI支持:

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

然后在绘制时同步Graphics的DPI缩放:

private void Form1_Paint(object sender, PaintEventArgs e)
{
    float dpiScale = e.Graphics.DpiY / 96f;
    // 转换鼠标坐标到Graphics的设备坐标
    int adjustedX = (int)(mouseX / dpiScale);
    int adjustedY = (int)(mouseY / dpiScale);
    e.Graphics.FillRectangle(Brushes.Black, new Rectangle(adjustedX, adjustedY, 10, 10));
}

3. 正确触发重绘

确保鼠标移动时调用Invalidate()触发Paint事件,而非直接用CreateGraphics()绘制(后者创建的Graphics对象不会自动适配窗体DPI,且绘制内容会被窗体刷新覆盖):

private void Form1_MouseMove(object sender, MouseEventArgs e)
{
    mouseX = e.X;
    mouseY = e.Y;
    Invalidate(); // 通知窗体重绘
}

额外检查

  • 确认窗体的AutoScaleMode设置为Dpi,而非Font,避免字体缩放影响坐标计算。
  • 不要手动修改Graphics.Transform属性,除非你明确知道坐标转换逻辑,否则会导致额外偏移。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 10:17:31