当在同一方向发现另一个标签时停止移动标签

Stop moving a label when another label found in the same direction

我的图片框上有很多标签。我想相对于光标移动一个标签,但是当移动方向上有另一个标签时,标签应该停止移动

这是我的代码

void lbl_MouseClick(object sender, MouseEventArgs e)
    {
        try
        {
            lblCutPaste = sender as Control;
        }
        catch (Exception err)
        {
            MessageBox.Show(err.Message);
        }
    }

    void lbl_MouseDown(object sender, MouseEventArgs e)
    {
        try
        {
            activeControl = sender as Control;
            previousLocation = e.Location;
            //  preloc = activeControl.Location;
            Cursor = Cursors.Hand;



        }
        catch (Exception err)
        {
            MessageBox.Show(err.Message);
        }
    }

    void lbl_MouseMove(object sender, MouseEventArgs e)
    {
        try
        {
            bool isCollide = false;
            if (activeControl == null || activeControl != sender)
                return;
            var location = activeControl.Location;
            location.Offset(e.Location.X - previousLocation.X, e.Location.Y - previousLocation.Y);

            if (location.X >= 0 && location.X <= activeControl.Parent.Width - activeControl.Width && location.Y >= 0 && location.Y <= activeControl.Parent.Height - activeControl.Height)
            {
                activeControl.Location = location;

            }
        }
        catch (Exception err)
        {
            MessageBox.Show(err.Message);
        }
    }

    void lbl_MouseUp(object sender, MouseEventArgs e)
    {
       activeControl = null;
        Cursor = Cursors.Default;

    }

这是一个工作示例;学习后你将不得不调整你的代码。将 lambda 提取到您的事件中应该不难。

它首先创建 20 个 Labels 并将它们添加到一个 PictureBox 中。它将每个 Label 与三个事件联系起来。它在拖动时为活动 Label 着色。

每个 Label 也被添加到 class 级别 List<T> 因此我们可以轻松地进行我们需要的检查。检查使用 LINQ 计算所有重叠标签。

它使用了 Rectangle.IntersectsWithPoint.Subtract 方法..

List<Label> myLabels = new List<Label>();
Label movingLabel = null;
Point mDown = Point.Empty;

private void button11_Click(object sender, EventArgs e)
{
    Random R = new Random(8);
    Size sz = pictureBox1.ClientSize;
    for (int i = 0; i < 20; i++)
    {
        Label lbl = new Label() {Text = "L " + i};
        lbl.Location = new Point(R.Next(sz.Width), R.Next(sz.Height));
        lbl.Parent = pictureBox1;
        myLabels.Add(lbl);

        lbl.BorderStyle = BorderStyle.FixedSingle;

        lbl.MouseDown += (ss, ee) =>
            {
                movingLabel = lbl;
                lbl.BackColor = Color.Bisque;
                mDown = ee.Location;  
            };

        lbl.MouseMove += (ss, ee) =>
            {
                if (ee.Button == MouseButtons.Left)
                {
                   Point nLoc = Point.Subtract(lbl.Location, 
                                      new Size(mDown.X - ee.X, mDown.Y - ee.Y));
                   Rectangle rlbNew = new Rectangle(nLoc, lbl.Size);
                   var overlapped = myLabels.Where(x => x != lbl && 
                              rlbNew.IntersectsWith(new Rectangle(x.Location, x.Size)));
                   if (overlapped.Count() == 0) lbl.Location = nLoc;
                }
            };

        lbl.MouseUp += (ss, ee) =>
            {
                movingLabel = null;
                lbl.BackColor = Color.Transparent;
            };
    }
}

请注意,我不在乎创建的 Labels 是否重叠,所以有些会重叠,而且它们不会分开,除非您一直拖动直到到达 'legal' 一个;然后它将跳过重叠的标签并到达新位置..

如果您愿意,可以编写逻辑代码以允许在移动时重叠,将背景色设为红色以表明这不正常,如果它仍然重叠,则跳回 MouseUp。您将需要为此存储原始位置。但拖动到合法位置可能就足够了,imo ..