我正试图创建一个Winforms应用程序,在其中一个屏幕上,我有一个图像和一些在运行时生成的按钮,现在我希望这些按钮始终与图像成比例。
例如 Hand1 按钮始终应该停留在图像的 Hand1 位置。
这是我的初始图像:
但在调整窗体大小时,它会变成这样:
我希望这些按钮不改变其大小并始终与图像成比例。
图像的 ImageSizeMode 是 StretchImage,而按钮没有被 Anchored (否则它们不会移动或开始拉伸/缩小)。
我该如何实现这种行为呢?
我正试图创建一个Winforms应用程序,在其中一个屏幕上,我有一个图像和一些在运行时生成的按钮,现在我希望这些按钮始终与图像成比例。
例如 Hand1 按钮始终应该停留在图像的 Hand1 位置。
这是我的初始图像:
但在调整窗体大小时,它会变成这样:
我希望这些按钮不改变其大小并始终与图像成比例。
图像的 ImageSizeMode 是 StretchImage,而按钮没有被 Anchored (否则它们不会移动或开始拉伸/缩小)。
我该如何实现这种行为呢?
这是一个简单完整的单按钮解决方案:
注意:缩放是相对于控件(按钮)的左上角计算的。如果需要修改缩放比例,例如到中间或下方/右侧,则必须调整缩放计算。否则,位置看起来不太精确,按钮将随着图像的调整而“漫游”。
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));
}
}
Fancier version:
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;
}
}
您希望保持距离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);
}
valter
您将不得不手动移动按钮。
为所有按钮选择原点。例如,“手 1” 按钮的原点可能是 (button.Width / 2; button.Height)
,“腿 2” 按钮的原点是 (0; button.Height)
。
计算并保存按钮原点的位置:(OriginalX; OriginalY)
。
当窗体调整大小时,通过比例缩放原始位置:(OriginalX * ScaleX; OriginalY * ScaleY)
。然后根据原点的新位置设置按钮的位置:(OriginalX * ScaleX - OriginX; OriginalY * ScaleY - OriginY)
。
按钮应锚定在左上角。