[ACCEPTED]-Is there any way to detect a mouseclick outside a user control?-mouseevent
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
andLeave
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 28Leave
event is raised for the TextBox and GroupBox, and 27 theEnter
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.
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.
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.
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.
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
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.