[ACCEPTED]-Is there any way to detect a mouseclick outside a user control?-mouseevent

Accepted answer
Score: 15

So I finally understand that you only want 46 it to close when the user clicks outside of it. In 45 that case, the Leave event should work just fine... For 44 some reason, I got the impression you wanted 43 it to close whenever they moved the mouse 42 outside of your custom dropdown. The Leave event 41 is raised whenever your control loses the 40 focus, and if the user clicks on something 39 else, it will certainly lose focus as the 38 thing they clicked on gains the focus.

The 37 documentation also says that this event 36 cascades up and down the control chain as 35 necessary:

The Enter and Leave events are hierarchical 34 and will cascade up and down the parent 33 chain until the appropriate control is reached. For 32 example, assume you have a Form with two 31 GroupBox controls, and each GroupBox control 30 has one TextBox control. When the caret 29 is moved from one TextBox to the other, the 28 Leave event is raised for the TextBox and GroupBox, and 27 the Enter event is raised for the other GroupBox 26 and TextBox.

Overriding your UserControl's 25 OnLeave method is the best way to handle this:

protected override void OnLeave(EventArgs e)
{
   // Call the base class
   base.OnLeave(e);

   // When this control loses the focus, close it
   this.Hide();
}

And 24 then for testing purposes, I created a form 23 that shows the drop-down UserControl on 22 command:

public partial class Form1 : Form
{
   private UserControl1 customDropDown;

   public Form1()
   {
      InitializeComponent();

      // Create the user control
      customDropDown = new UserControl1();

      // Add it to the form's Controls collection
      Controls.Add(customDropDown);
      customDropDown.Hide();
   }

   private void button1_Click(object sender, EventArgs e)
   {         
      // Display the user control
      customDropDown.Show();
      customDropDown.BringToFront();   // display in front of other controls
      customDropDown.Select();         // make sure it gets the focus
   }
}

Everything works perfectly with 21 the above code, except for one thing: if the user 20 clicks on a blank area of the form, the 19 UserControl doesn't close. Hmm, why not? Well, because 18 the form itself doesn't want the focus. Only 17 controls can get the focus, and we didn't click 16 on a control. And because nothing else stole 15 the focus, the Leave event never got raised, meaning 14 that the UserControl didn't know it was 13 supposed to close itself.

If you need the 12 UserControl to close itself when the user 11 clicks on a blank area in the form, you 10 need some special case handling for that. Since 9 you say that you're only concerned about 8 clicks, you can just handle the Click event for the 7 form, and set the focus to a different control:

protected override void OnClick(EventArgs e)
{
   // Call the base class
   base.OnClick(e);

   // See if our custom drop-down is visible
   if (customDropDown.Visible)
   {
      // Set the focus to a different control on the form,
      // which will force the drop-down to close
      this.SelectNextControl(customDropDown, true, true, true, true);
   }
}

Yes, this 6 last part feels like a hack. The better 5 solution, as others have mentioned, is to 4 use the SetCapture function to instruct Windows to capture 3 the mouse over your UserControl's window. The 2 control's Capture property provides an even simpler way 1 to do the same thing.

Score: 3

Technically, you'll need to p/invoke SetCapture() in 13 order to receive click events that happen 12 outside of your control.

But in your case, handling 11 the Leave event, as @Martin suggests, should 10 be sufficient.

EDIT: While looking for an usage 9 example for SetCapture(), I came across the Control.Capture property, of 8 which I was not aware. Using that property 7 means you won't have to p/invoke anything, which 6 is always a good thing in my book.

So, you'll 5 have to set Capture to true when showing the dropdown, then 4 determine if the mouse pointer lies inside 3 the control in your click event handler 2 and, if it doesn't, set Capture to false and close the 1 dropdown.

Score: 2

Handle the Form's MouseDown event, or override the 9 Form's OnMouseDown method:

enter code here

And then:

protected override void OnMouseDown(MouseEventArgs e)
{

    if (!theListBox.Bounds.Contains(e.Location)) 
    {
        theListBox.Visible = false;
    }
}

The Contains method 8 old System.Drawing.Rectangle can be used to indicate if a point 7 is contained inside a rectangle. The Bounds 6 property of a Control is the outer Rectangle defined 5 by the edges of the Control. The Location property 4 of the MouseEventArgs is the Point relative to the Control 3 which received the MouseDown event. The Bounds property 2 of a Control in a Form is relative to the 1 Form.

Score: 0

You are probably looking for the leave event:

http://msdn.microsoft.com/en-us/library/system.windows.forms.control.leave.aspx

Leave 1 occurs when the input focus leaves the control.

Score: 0

I just wanted to share this. It is probably 13 not a good way of doing it that way, but 12 looks like it works for drop down panel 11 that closes on fake "MouseLeave", I tried 10 to hide it on Panel MouseLeave but it does 9 not work because moving from panel to button 8 leaves the panel because the button is not 7 the panel itself. Probably there is better 6 way of doing this but I am sharing this 5 because I used about 7 hours figuring out 4 how to get it to work. Thanks to @FTheGodfather

But 3 it works only if the mouse moves on the 2 form. If there is a panel this will not 1 work.

    private void click_to_show_Panel_button_MouseDown(object sender, MouseEventArgs e)
    {
        item_panel1.Visible = true; //Menu Panel
    }



    private void Form1_MouseMove(object sender, MouseEventArgs e)
    {
        if (!item_panel1.Bounds.Contains(e.Location))
        {
            item_panel1.Visible = false; // Menu panel 
        }
    }

More Related questions