保持按钮位置与调整图像大小成比例

时间:2014-09-10 11:45:54

标签: c# winforms

我正在尝试创建Winforms应用程序并在其中一个屏幕中,我有一个图像和一些在运行时生成的按钮,现在我想要的是这些按钮应该始终与图像成比例

例如Hand1 Button应始终保留在Image的Hand1

的位置

这是我的初始图片

Initial Image

但在调整表单大小时,它就像这样

enter image description here

我想要的是这些按钮不应改变它们的大小,并且始终与图像保持成比例。

Image的ImageSizeMode是StretchImage,按钮没有锚定(否则它们不会移动或开始拉伸/收缩。

我怎样才能实现这种行为。 ?

3 个答案:

答案 0 :(得分:1)

此解决方案适用于 hand1 按钮。同样的逻辑也适用于其他按钮。

enter image description here

您希望距离c和d 保持不变。首先衡量 a,b,c,d 和:

double dblHand1X, dblHand1Y;

private void Form1_Load(object sender, EventArgs e)
    {
        dblHand1X= (double)b / (double)pictureBox1.Width;
        dblHand1Y= (double)a / (double)pictureBox1.Height;
    }

private void pictureBox1_SizeChanged(object sender, EventArgs e)
    {
        int x, y;

        x = (int)(dblHand1X* (double)pictureBox1.Width) + pictureBox1.Location.X;
        y = (int)(dblHand1Y* (double)pictureBox1.Height) + pictureBox1.Location.Y;

        x -= d;
        y -= c;
        Hand1.Location = new Point(x, y);
    }

瓦尔特

答案 1 :(得分:0)

您必须手动移动按钮。

  1. 选择所有按钮的来源。例如,起源于" Hand 1"按钮可能是(button.Width / 2; button.Height)和" Leg 2"的起源。按钮为(0; button.Height)

  2. 计算并保存按钮来源的位置:(OriginalX; OriginalY)

  3. 调整表单大小时,按比例乘以原始位置:(OriginalX * ScaleX; OriginalY * ScaleY)。然后根据新来源位置设置按钮的位置:(OriginalX * ScaleX - OriginX; OriginalY * ScaleY - OriginY)

  4. 按钮应固定在左上角。

答案 2 :(得分:0)

这是一个简单,完整的单个按钮解决方案:

注意:比例是相对于控件(按钮)的左上角计算的。如果需要修改缩放比例,例如中间或下/右,则必须调整缩放计算。否则,该位置看起来不会很精确,并且在调整图像大小时按钮将“漂移”。

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

public partial class Form1 : Form
{
    // X, Y scaling variables for btn1
    private float _btn1xScale;
    private float _btn1yScale;

    public Form1()
    {
        InitializeComponent();

        // The scale is really the % of btn X & Y along image width and height:
        // Calculate X and Y scale from initial location and position in image
        // Has to happen AFTER InitializeComponent is called!
        _btn1xScale = btn1.Location.X / (float)pictureBox1.Width;
        _btn1yScale = btn1.Location.Y / (float)pictureBox1.Height;
    }

    private void pictureBoxResize(object sender, EventArgs e)
    {
        // adjust position based on 
        btn1.Location = new Point(
            (int)(pictureBox1.Width * _btn1xScale), 
            (int)(pictureBox1.Height * _btn1yScale));
    }
}

发烧友版本:

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;

public partial class Form1 : Form
{
    private List<ControlScaler> _buttonsToScale = new List<ControlScaler>();

    public Form1()
    {
        InitializeComponent();

        // Has to happen AFTER InitializeComponent is called!
        _buttonsToScale.Add(new ControlScaler(btn1, pictureBox1));
        _buttonsToScale.Add(new ControlScaler(btn2, pictureBox1));
    }

    private void pictureBoxResize(object sender, EventArgs e)
    {
        foreach (var control in _buttonsToScale)
            control.AdjustPositionToScale();
    }
}

public class ControlScaler
{
    // X, Y scaling variables
    private float _btn1xScale;
    private float _btn1yScale;

    private Control _scaledControl;
    private readonly Control _scaleTo;

    public ControlScaler(Control scaledControl, Control scaleTo)
    {
        _scaledControl = scaledControl;
        _scaleTo = scaleTo;

        _btn1xScale = scaledControl.Location.X / (float)scaleTo.Width;
        _btn1yScale = scaledControl.Location.Y / (float)scaleTo.Height;
    }

    public void AdjustPositionToScale()
    {
        var newLocation = new Point(
            (int)(_scaleTo.Width * _btn1xScale),
            (int)(_scaleTo.Height * _btn1yScale));

        _scaledControl.Location = newLocation;
    }
}