【问题标题】:Resize form as if it were a picture像图片一样调整表格大小
【发布时间】:2018-12-26 07:10:54
【问题描述】:

我正在使用 Visual Studio 2017 的表单设计器,但我发现无法以模拟图片调整大小的方式调整表单大小。当我将表单大小调整为 25% 时,我希望里面的所有项目都增长 25%,并且每个控件之间的间距增长该数量,控件和表单边框之间的间距增长 25%。

我附上了一张情况的 gif 图像

What happens

When using anchor

What i want

有人可以指出一个图书馆/方法来实现这一点吗?

【问题讨论】:

  • 你可以使用 AutoScaleMode & AutoSizeMode
  • 我已经尝试过使用停靠和锚点,问题是控件保持绝对距离的间距,这意味着如果我增加表单的大小,控件和边框之间的间距将正确增长,但每个控件之间的间距保持不变。我编辑了问题以反映这一点
  • 这对我来说似乎是一个 XY 问题。数据输入表单不是图片,因此尝试将它们视为此类是非常不寻常的。您的预览显示,即使是标题栏和标准窗口镶边(表单图标、最大/最小/关闭按钮)也会在缩小时缩放。如果您的目标是适应不同的屏幕尺寸、比例,Windows 本身会为您做很多事情。这里的实际目标是什么?用例是什么?
  • @J.Joe 你能说说你在哪一边锚定吗?

标签: c# forms winforms


【解决方案1】:

这不是开箱即用的;我仍然认为这不是很有用;但也许您的特殊应用确实需要它..

这是下面几行的结果:

下面是示例代码:

首先,我们需要通过在每个控件的Tag存储旧的边界以及原始父大小来进行设置:

    // pick the top parent; in my case it wa a TabPage (not shown)
    Control ctrl = pickTheParent;  
    foreach (Control c in ctrl.Controls) StoreBounds(ctrl, c);
    ctrl.Resize += (ss, ee) =>
    {
        foreach (Control c in ctrl.Controls)  ScaleBounds(c);
    };

我们还为父级的Resize 事件绑定了一个大小调整例程。

存储和调整大小都必须发生在所有控件,包括嵌套控件;所以它们是递归的..:

void StoreBounds(Control parent, Control ctl)
{
    ctl.Tag = new Tuple<Size, Rectangle>(parent.ClientSize, ctl.Bounds);
    // **
    foreach (Control c in ctl.Controls)  StoreBounds(ctl, c);
}


void ScaleBounds(Control ctl)
{
    ctl.Bounds = ScaledBounds(ctl);
    foreach (Control c in ctl.Controls)  ScaleBounds(c);
}

大小只是计算旧的比率,并从中计算出新的比率:

Rectangle ScaledBounds(Control c)
{
    if (c.Tag == null) return c.Bounds;
    Rectangle old = ((Tuple<Size, Rectangle>)c.Tag).Item2;
    Size frame1 = ((Tuple<Size, Rectangle>)c.Tag).Item1;
    Size frame2 = c.Parent.ClientSize;
    float rx = 1f * frame2.Width / frame1.Width;
    float ry = 1f * frame2.Height / frame1.Height;
    int x = (int)(old.Left * rx);
    int y = (int)(old.Top * ry);
    int w = (int)(old.Width * rx);
    int h = (int)(old.Height * ry);
    return new Rectangle(x,y,w,h);
}

请注意,为了显示效果,我必须关闭所有 AutoSize 属性。

另请注意,所有Anchors(以及任何Docks)都已删除。要自动执行此操作,您可以在存储代码中添加一两行代码 (**)..:

 ctl.Anchor = AnchorStyles.None;

删除Docking 取决于您,也许一些,例如Fill,实际上仍然有用..?

还请注意,该示例严格处理SizeLocation;其他属性不受影响。对于某些人,尤其是Fonts,可以添加更多代码;例如将第三个Item 添加到Tuple 以存储原始FontSize.. 对于其他人,例如Border 宽度,我想不出合理的大小调整方法。

PictureBox 显然被设置为Zoom

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-19
    • 2023-03-06
    • 2015-08-06
    • 1970-01-01
    • 1970-01-01
    • 2021-01-30
    • 2011-07-19
    相关资源
    最近更新 更多