Search code examples
c#show-hidepictureboxmouseentermouseleave

Show/Hide Buttons inside a PictureBox


I have a problem when I show/hide some buttons inside a PictureBox , they show/hide but I can't click them, if I disable the hide part in MouseLeave event it works but when I make it hide, not working for some reason that I can't understand.

Here is the code:

    private void Form1_Load(object sender, EventArgs e)
    {
        PictureBox picB = new PictureBox();
        Button btn1 = new Button();
        Button btn2 = new Button();
        picB.Size = new Size(130, 70);
        btn1.Text = "btn1";
        btn2.Text = "btn2";
        btn1.Hide();
        btn2.Hide();
        picB.Controls.Add(btn1);
        picB.Controls.Add(btn2);
        flp.Controls.Add(picB);
        picB.MouseEnter += picB_MouseEnter;
        picB.MouseLeave += picB_MouseLeave;
        btn1.MouseClick += btn1_MouseClick;
        btn2.MouseClick += btn2_MouseClick;
    }

    private void picB_MouseEnter(object sender, EventArgs e)
    {
        PictureBox pb = (PictureBox)sender;
        Button bt1 = (Button)pb.Controls[0];
        Button bt2 = (Button)pb.Controls[1];
        bt1.Show();
        bt2.Show();
    }

    private void picB_MouseLeave(object sender, EventArgs e)
    {
        PictureBox pb = (PictureBox)sender;
        Button bt1 = (Button)pb.Controls[0];
        Button bt2 = (Button)pb.Controls[1];
        bt1.Hide();
        bt2.Hide();
    }

    private void btn1_MouseClick(object sender, EventArgs e)
    {
        MessageBox.Show("Button 1 pressed.");
    }

    private void btn2_MouseClick(object sender, EventArgs e)
    {
        MessageBox.Show("Button 2 pressed.");
    }

Solution

  • You can simply test if the mouse is on/off both the PictureBox and your Buttons:

    private void picB_MouseLeave(object sender, EventArgs e)
    {
        PictureBox pb = (PictureBox)sender;
        Button bt1 = (Button)pb.Controls[0];
        Button bt2 = (Button)pb.Controls[1];
    
        Point p = Control.MousePosition;
        if (bt1.ClientRectangle.Contains(bt1.PointToClient(p))  ||
            bt2.ClientRectangle.Contains(bt2.PointToClient(p))) return;
    
        bt1.Hide();
        bt2.Hide();
    }