简体   繁体   中英

C# WindowsForms - Hide control after clicking outside of it

C# WindowsForms - Hide control after clicking outside of it

I have a picturebox (fe 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.

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.

使用控件的LostFocus事件(在您的情况下,是一个PictureBox控件)

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM