3

C# WindowsForms - Hide control after clicking outside of it

I have a picturebox (f.e. picturebox1) which is not visible as default. When I click a button (let's say button1) the picturebox1 will show up. Now -> I need the picturebox1 to become hidden again when I click outside of it (on form itself or any other control). It works the same as a contextmenu would work.

I have no idea how to do it since any "Click_Outside" event doesn't exist. Is there any simple way to do this? Thanks.

Michal Hromas
  • 75
  • 1
  • 7
  • Use the MouseDown event. – glenebob May 07 '16 at 20:34
  • The 2nd answer (LB's) [here](http://stackoverflow.com/questions/7934629/c-sharp-application-wide-left-mouse-click-event) is short and rather simple, although one might argue that anything with wndproc is rather enigmatic, a word which here means 'anything but simple'.. Simply copy it to your form and replace DoIt by picturebox.Hide() – TaW May 08 '16 at 08:59

4 Answers4

3

Here is a simple solution, albeit not one that is totally easy to fully understand as it does involve catching the WndProc event and using a few constants from the Windows inderds..:

This is the obvious part:

private void button1_Click(object sender, EventArgs e)
{
    pictureBox1.Show();
}

Unfortunately we can't use the pictureBox1.LostFocus event to hide the Picturebox.

That is because only some controls can actually receive focus when clicking them; a Button or other interactive controls like a ListBox, a CheckBox etc can, too.

But a Panel, a PictureBox and also the Form itself can't receive focus this way. So we need a more global solution.

As ever so often the solution comes form the depths of the Windows message system:

const int WM_PARENTNOTIFY = 0x210;
const int WM_LBUTTONDOWN = 0x201;

protected override void WndProc(ref Message m)
{
    if (m.Msg == WM_LBUTTONDOWN || (m.Msg == WM_PARENTNOTIFY && 
        (int)m.WParam == WM_LBUTTONDOWN))
        if (!pictureBox1.ClientRectangle.Contains( 
                         pictureBox1.PointToClient(Cursor.Position))) 
            pictureBox1.Hide();
    base.WndProc(ref m);
}

Note that we need to make sure that you can still clcik on the PictureBox itself; so we check if the mouse is inside its ClientRectangle..

Simply add this to the form code and every click outside the PictureBox will hide it.

TaW
  • 53,122
  • 8
  • 69
  • 111
0

Use the LostFocus event of the control (in your case, a PictureBox control)

Jan Paolo Go
  • 5,842
  • 4
  • 22
  • 50
  • LostFocus is not a click outside the control. – Steve May 07 '16 at 20:43
  • This will only work if a) the focus was actually set on the PB in code and b) one clicks on a control that can receive focus. The form can't. So you need some more code.. – TaW May 07 '16 at 20:44
0

As you said, the ClickOutside doesn't exist, so you have few choices:

Loop through all the controls of your form (Form.Controls) and add a click event that hides the PictureBox excluding your "Show" button.

You can intercept the mouse click message at the source like in this example: intercept

Community
  • 1
  • 1
user4388177
  • 2,433
  • 3
  • 16
  • 30
0

The easiest way is this: Copy and paste the following method anywhere in your code:

private void mouseClick(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Left && pictureBox1.Visible == true)
            pictureBox1.Visible = false;
    }

then inside your form_Load Event copy and paste the following code:

foreach (Control ctrl in this.Controls)
    if (ctrl is GroupBox || ctrl is .....)
        ctrl.MouseClick += mouseClick;

of course you should repeat this loop for every groupBox within another groupBox and replace the dots with textbox, button, combobox, label, ... according to what controls you have