当在同一方向发现另一个标签时停止移动标签
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.IntersectsWith
和 Point.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 ..
我的图片框上有很多标签。我想相对于光标移动一个标签,但是当移动方向上有另一个标签时,标签应该停止移动
这是我的代码
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.IntersectsWith
和 Point.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 ..