我正在开发简单的winform应用程序,我想在主窗体中制作一张可以移动的图片(盒子)。但是,我想确保图片不能跨越边界。主要形式本身应保持可调整大小。
图像本身的分辨率为200x200。我已将父图片框的边框样式设置为“FixedSingle”,这使得图片框控件的总尺寸为202x202。
但是我仍然可以将图片框略微移出winform。我在这做错了什么?
private Point _MouseDownLocation;
private Size _FormSize;
private void Form1_Load(object sender, EventArgs e) => this._FormSize = Size;
private void Form1_Resize(object sender, EventArgs e) => this._FormSize = ((Form)sender).Size;
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
_MouseDownLocation = e.Location;
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
int newX = e.X + pictureBox1.Left - _MouseDownLocation.X;
int newY = e.Y + pictureBox1.Top - _MouseDownLocation.Y;
int rightBoundary = _FormSize.Width - pictureBox1.Width;
int bottomBoundary = _FormSize.Height - pictureBox1.Height - statusStrip1.Height;
if (newX <= rightBoundary && newX >= 0 && newY <= bottomBoundary && newY >= 0)
pictureBox1.Location = new Point(newX, newY);
}
}
答案 0 :(得分:1)
您应该单独评估限制并将其限制为一个if
语句:
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
int newX = e.X + pictureBox1.Left - _MouseDownLocation.X;
int newY = e.Y + pictureBox1.Top - _MouseDownLocation.Y;
int rightBoundary = ClientSize.Width - pictureBox1.Width;
int bottomBoundary = ClientSize.Height - pictureBox1.Height - statusStrip1.Height;
if (newX > rightBoundary)
newX = rightBoundary;
else if (newX < 0)
newX = 0;
if (newY > bottomBoundary)
newY = bottomBoundary;
else if (newY < 0)
newY = 0;
pictureBox1_MouseMove.Location = new Point(newX, newY);
}
}
这可能会通过一些更有创意的编码缩短,但你应该明白这一点。如果边界超出限制,请将其设置为最接近的限制。这样,如果拖动到底部,图片将停止在Y方向上移动,同时仍然可以在X方向上移动。
另一个问题是,正如另一个答案所示,使用ClientSize
与Size
。
答案 1 :(得分:1)
代码的主要问题是因为使用Size
的{{1}}属性。
您应该使用表单的ClientSize
,而不是使用表单的Form
。
客户端大小返回表单客户区的大小(不包括标题栏和边框),而大小则返回整个表单的大小,包括非客户区。
表单客户区的大小是表单的大小 排除边框和标题栏。表单的客户区域是 可以放置控件的表单区域。你可以用它 在执行图形时获取适当尺寸的属性 操作或在表单上调整和定位控件时。要得到 整个表单的大小,使用Size属性或使用 个别属性高度和宽度。
注意
您无需在字段中保留大小,因此请移除Size
和Load
事件处理程序,并在您需要的任何位置使用Resize
。
为移动控件分配新位置时,请使用单独的条件来检测边缘碰撞。现在如果控件与上边缘碰撞,你也会阻止向左和向右移动!
答案 2 :(得分:0)
非常感谢您的回复。现在这就像一个魅力。但是我仍然需要减去statusstrip的高度来获得正确的y轴。
private Point _MouseDownLocation;
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
_MouseDownLocation = e.Location;
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
int newX = e.X + pictureBox1.Left - _MouseDownLocation.X;
int newY = e.Y + pictureBox1.Top - _MouseDownLocation.Y;
int rightBoundary = this.ClientSize.Width - pictureBox1.Width;
int bottomBoundary = this.ClientSize.Height - pictureBox1.Height - statusStrip1.Height;
if (newX > rightBoundary)
newX = rightBoundary;
else if (newX < 0)
newX = 0;
if (newY > bottomBoundary)
newY = bottomBoundary;
else if (newY < 0)
newY = 0;
pictureBox1.Location = new Point(newX, newY);
}
}
我不确定是否应该为此创建一个新的SO问题,但由于这是一个后续问题,我在此处添加:
当使主窗体缩小并将边框拉过内容/图片框时,它可以进入不可到达的区域。作为用户,我希望在调整表单大小时内容会移动。
我该怎样防止这种情况?