可移动的控制和形式边界

时间:2018-04-05 20:48:45

标签: c# winforms

我正在开发简单的winform应用程序,我想在主窗体中制作一张可以移动的图片(盒子)。但是,我想确保图片不能跨越边界。主要形式本身应保持可调整大小。

图像本身的分辨率为200x200。我已将父图片框的边框样式设置为“FixedSingle”,这使得图片框控件的总尺寸为202x202。

但是我仍然可以将图片框略微移出winform。我在这做错了什么?

enter image description here

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);                     
    }
}

3 个答案:

答案 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方向上移动。

另一个问题是,正如另一个答案所示,使用ClientSizeSize

答案 1 :(得分:1)

代码的主要问题是因为使用Size的{​​{1}}属性。

您应该使用表单的ClientSize,而不是使用表单的Form。 客户端大小返回表单客户区的大小(不包括标题栏和边框),而大小则返回整个表单的大小,包括非客户区。

  

表单客户区的大小是表单的大小   排除边框和标题栏。表单的客户区域是   可以放置控件的表单区域。你可以用它   在执行图形时获取适当尺寸的属性   操作或在表单上调整和定位控件时。要得到   整个表单的大小,使用Size属性或使用   个别属性高度和宽度。

注意

  • 您无需在字段中保留大小,因此请移除SizeLoad事件处理程序,并在您需要的任何位置使用Resize

    < / LI>
  • 为移动控件分配新位置时,请使用单独的条件来检测边缘碰撞。现在如果控件与上边缘碰撞,你也会阻止向左和向右移动!

答案 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问题,但由于这是一个后续问题,我在此处添加:

当使主窗体缩小并将边框拉过内容/图片框时,它可以进入不可到达的区域。作为用户,我希望在调整表单大小时内容会移动。

我该怎样防止这种情况?

enter image description here