表单可以配置为固定的坐标范围而不管其大小吗?

问题描述

我正在使用 System.Drawing 中的类(使用 C# 编码,针对 .NET 4.7.2)在表单上进行一些基本绘图。

我想将表单配置为无论表单大小如何,客户区的坐标范围都是 (0,0) 到 (100,100)。换句话说,如果我们最大化表单,右下角的坐标应该还是(100,100)。

这可以在不需要滚动我自己的缩放函数的情况下完成吗?

解决方法

您可以使用 Graphics.ScaleTransform() 执行此操作。

这是一个设置缩放比例的示例,使窗口坐标的宽度和高度从 0 到 100。请注意,每当窗口大小发生变化时,您都必须重新绘制并重新计算变换:

using System.Drawing;
using System.Windows.Forms;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            this.ResizeRedraw = true;
            InitializeComponent();
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            setScaling(e.Graphics);
            e.Graphics.DrawRectangle(Pens.Black,5,90,90); // Draw rectangle close to the edges.
        }

        void setScaling(Graphics g)
        {
            const float WIDTH  = 100;
            const float HEIGHT = 100;

            g.ScaleTransform(ClientRectangle.Width/WIDTH,ClientRectangle.Height/HEIGHT);
        }
    }
}

这不考虑窗口的纵横比,因此即使您绘制的是正方形,如果窗口不是正方形,它也会显示为矩形。

如果您想保持方形纵横比,也可以通过计算 TranslateTransform() 来实现。请注意,这会在顶部+底部或左侧+右侧引入一个空白区域,具体取决于窗口的纵横比:

void setScaling(Graphics g)
{
    const double WIDTH  = 100;
    const double HEIGHT = 100;

    double targetAspectRatio = WIDTH / HEIGHT;
    double actualAspectRatio = ClientRectangle.Width / (double)ClientRectangle.Height;

    double h = ClientRectangle.Height;
    double w = ClientRectangle.Width;

    if (actualAspectRatio > targetAspectRatio)
    {
        w = h * targetAspectRatio;
        double x = (ClientRectangle.Width - w) / 2;
        g.TranslateTransform((float)x,0);
    }
    else
    {
        h = w / targetAspectRatio;
        double y = (ClientRectangle.Height - h) / 2;
        g.TranslateTransform(0,(float)y);
    }

    g.ScaleTransform((float)(w / WIDTH),(float)(h / HEIGHT));
}