如何在Bounds.Contains(e.Location)中的List <picturebox>中找到最顶层的picbox?</picturebox>

时间:2012-08-08 14:53:20

标签: c# winforms picturebox

我在panel1_MouseMove事件中遇到了一个问题。我在List pBoxes中有3个picturebox,它们都被绘制到面板和放大器中。图片框控件设置为Visible = false。

问题是当图像重叠时,当我点击一个图像时,它可能会选择它背后的图片框。像这样enter image description here

以下是代码:

    private void panel1_MouseMove(object sender, MouseEventArgs e)
{
if (picturebox1.Bounds.Contains(e.Location) && !picturebox1.Visible)
{
picturebox1.Show();
picturebox2.Hide();
picturebox3.Hide();
}
if (picturebox2.Bounds.Contains(e.Location) && !picturebox2.Visible)
{
picturebox1.Hide();
picturebox2.Show();
picturebox3.Hide();
}
if (picturebox3.Bounds.Contains(e.Location) && !picturebox3.Visible)
{
picturebox1.Hide();
picturebox2.Hide();
picturebox3.Show();
}

任何帮助都会很高兴,并且是的,我必须使用Bounds.Contains作为我的特定应用程序。查看我的问题的另一种方法是我尝试创建一个没有Visible控件的pictureBox1__MouseClick事件。

1 个答案:

答案 0 :(得分:1)

你可以尝试这样的事情。我添加了三个重叠的PictureBox,它们有三种不同的背景颜色供测试。

初始表单设置:

private bool isDragging = false;
private Point dragOffset = Point.Empty;
private PictureBox dragBox;

public Form1() {
  InitializeComponent();

  panel1.MouseDown += new MouseEventHandler(panel1_MouseDown);
  panel1.MouseMove += new MouseEventHandler(panel1_MouseMove);
  panel1.MouseUp += new MouseEventHandler(panel1_MouseUp);
  panel1.Paint += new PaintEventHandler(panel1_Paint);
  panel1.DragEnter += new DragEventHandler(panel1_DragEnter);
  panel1.DragDrop += new DragEventHandler(panel1_DragDrop);
}

拖放事件:

void panel1_DragDrop(object sender, DragEventArgs e) {
  dragBox.Location = panel1.PointToClient(
          new Point(e.X - dragOffset.X, e.Y - dragOffset.Y));
  panel1_MouseUp(null, null);
}

void panel1_DragEnter(object sender, DragEventArgs e) {
  e.Effect = DragDropEffects.Move;
}

鼠标事件:

void panel1_MouseMove(object sender, MouseEventArgs e) {
  if (dragBox != null && !isDragging) {
    isDragging = true;
    panel1.DoDragDrop(dragBox, DragDropEffects.Move);
  }
}

void panel1_MouseDown(object sender, MouseEventArgs e) {
  if (e.Button == MouseButtons.Left) {
    foreach (PictureBox pb in panel1.Controls.OfType<PictureBox>()
             .OrderBy(x => panel1.Controls.GetChildIndex(x))) {

      if (pb.Bounds.Contains(e.Location)) {
        pb.BringToFront();
        pb.Visible = true;
        dragBox = pb;
        dragOffset = new Point(e.X - pb.Left, e.Y - pb.Top);
        panel1.Invalidate();
        break;
      }
    }
  }
}

void panel1_MouseUp(object sender, MouseEventArgs e) {
  foreach (PictureBox pb in panel1.Controls.OfType<PictureBox>()) {
    pb.Visible = false;
  }
  dragBox = null;
  isDragging = false;
}

绘制事件:

void panel1_Paint(object sender, PaintEventArgs e) {
  foreach (PictureBox pb in panel1.Controls.OfType<PictureBox>()
           .OrderByDescending(x => panel1.Controls.GetChildIndex(x))) {
    e.Graphics.FillRectangle(new SolidBrush(pb.BackColor), pb.Bounds);
  }
}

它使用父面板的GetChildIndex来获取面板内最高的PictureBox控件,如果找到它,则使“单击”控件可见并显示在前面,以便更新子索引。

由于PictureBoxes总是被隐藏(除非被拖动),因此这段代码会将正确的PictureBox带到前面。我添加了我的绘制事件,它以 reverse 顺序绘制PictureBox,以便最后绘制最高的框。

更改代码以在MouseDown上显示所选的PictureBox,然后在MouseUp上再次隐藏它。

添加了拖放代码。