Прекратить перемещение метки, когда другая метка найдена в том же направлении
У меня много ярлыков на картинке. Я хочу переместить метку относительно курсора, но метка должна перестать двигаться, когда в направлении движения есть другая метка
Вот мой код
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;
}
1 ответ
Вот рабочий пример; вам придется адаптировать свой код после изучения. Не должно быть трудно вытащить лямбду в ваши события.
Сначала создается 20 Labels
и добавить их на PictureBox
, Он подключает каждый Label
с тремя событиями. Окрашивает активный Label
пока его тащат.
каждый Label
также добавляется на уровень класса 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
перекрываются, так что некоторые делают, и, как они делают, не могут быть раздвинуты, если вы не продолжите тянуть, пока не достигнет "законного"; затем он перепрыгнет через перекрывающуюся метку и перейдет на новую позицию.
Если вы хотите, чтобы вы могли кодировать логику, чтобы разрешить перекрытие при движении, сделайте красный цвет фона, чтобы показать, что это не нормально, и включите его снова MouseUp
если это все еще накладывается. Вам нужно будет сохранить исходную позицию для этого.. Но перетаскивание в легальную позицию, как она есть, может быть достаточно хорошим, я думаю..