How to close a form when the user clicks outside the form window?

I want to close the System.Windows.Forms.Form file if the user clicks somewhere outside of it. I tried using IMessageFilter, but even then none of the messages are passed to PreFilterMessage. How to get clicks outside the form window?

+4
source share
7 answers

Thanks p-daddy to this question , I found this solution which allows me to use ShowDialog:

protected override void OnShown(EventArgs e) { base.OnShown(e); this.Capture = true; } protected override void OnCaptureChanged(EventArgs e) { if (!this.Capture) { if (!this.RectangleToScreen(this.DisplayRectangle).Contains(Cursor.Position)) { this.Close(); } else { this.Capture = true; } } base.OnCaptureChanged(e); } 
+4
source

In your form, Deactivate the event, put "this.Close ()". Your form will be closed as soon as you click elsewhere on Windows.

Update. I think that now you have the Volume button, and inside the Click event you create an instance of the VolumeSlider form and display it by calling ShowDialog (), which blocks until the user closes the pop-up form. In the next line, you read the volume that you selected user, and use it in your program.

This is normal, but as you noticed, it forces the user to explicitly close the pop-up window in order to return to the main program. Show () is the method that you really want to use here in your popup form, but Show () does not block, which means that the Click event on your main form ends without knowing what the new volume should be.

A simple solution is to create a public method in your main form as follows:

 public void SetVolume(int volume) { // do something with the volume - whatever you did before with it } 

Then in your "Click" button (also in the main form) you will create a VolumeSlider as follows:

 VolumeSlider slider = new VolumeSlider(); slider.Show(this); // the "this" is needed for the next step 

In the VolumeSlider form, since the user is working with a scrollbar (I assume), you put this code in the ValueChanged event with a scrollbar (I think it is):

 MainForm owner = (MainForm)this.Owner; owner.SetVolume(scrollbar.Value); 

And then in the VolumeSlider form, deactivate the event that you would put this.Close (), as mentioned above. Your form will behave as expected.

+7
source

With Simon's solution, I had the same problem described by Noam. With the following code, I avoid the "Click" problem ...

 protected override void WndProc(ref Message m) { base.WndProc(ref m); // if click outside dialog -> Close Dlg if (m.Msg == NativeConstants.WM_NCACTIVATE) //0x86 { if (this.Visible) { if (!this.RectangleToScreen(this.DisplayRectangle).Contains(Cursor.Position)) this.Close(); } } } 
+4
source

If this is a child form in an MDI application, you can grab a click on the parent form, otherwise the solution will be messy.

I'm not sure if you offer intuitive user interface behavior. Are you sure this is the best design?

0
source

If you are trying to create a popup that looks a bit like a menu, except that it allows you to interact with your controls, you can try placing a usercontrol inside the toolbar's drop-down list.

0
source

EASY WAY: on Form1 use this code to invoke form2:

 Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Form2.Owner = Me Form2.Show() End Sub 

and then use this code again in form1:

 Private Sub Form1_MouseClick(sender As Object, e As MouseEventArgs) Handles Me.MouseClick If Form2.IsHandleCreated = True Then Form2.Close() End If End Sub 
0
source

it's simple:

 private void button1_Click(object sender, EventArgs e) { Form f = new Form(); f.LostFocus +=new EventHandler(f_LostFocus); f.Show(); } void f_LostFocus(object sender, EventArgs e) { Form f = sender as Form; f.Close(); f.Dispose(); } 
-1
source

All Articles