Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I close a form when a user clicks outside the form's window?

Tags:

c#

forms

click

I want to close a System.Windows.Forms.Form if the user clicks anywhere outside it. I've tried using IMessageFilter, but even then none of the messages are passed to PreFilterMessage. How do I receive clicks outside a form's window?

like image 200
Simon Avatar asked Nov 18 '08 11:11

Simon


People also ask

How do I close a Windows Form?

When we need to exit or close opened form then we should use "this. Close( )" method to close the form on some button click event. When we are running a winform application & need to exit or close SUB APPLICATION or CURRENT THREAD then we should use "System. Windows.

What is the code used to close a form from within the form?

Close() function is used to close a Form in a Windows Form application in C#. We can use the Form. Close() function inside the button click event to close the specified form by clicking a button.

How do you close a hidden form?

In order to totally close a C# application, including the hidden forms, you can use the following command in the event code of the “Exit” control: Application. Exit(); Application.

How do I close a Windows Form in VB net?

If you want to close the form then use Me. Close() instead. The Load event will fire again when you create the new instance.


4 Answers

In your form's Deactivate event, put "this.Close()". Your form will close as soon as you click anywhere else in Windows.

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

This is OK, but as you've noticed it forces the user to explicitly close the popup in order to get back to the main program. Show() is the method you really want to use here on your popup form, but Show() doesn't block which means the Click event back on your main form finishes without knowing what the new volume is supposed to be.

A simple solution is to create a public method on your main form like this:

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

Then, in your Volume button's Click event (also on the main form), you make the VolumeSlider appear like so:

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

In the VolumeSlider form, as the user works the (I guess) scrollbar, you put this code in the scrollbar's ValueChanged event (I think that's what it is):

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

And then in the VolumeSlider form's Deactivate event you would put this.Close() as mentioned above. Your form will then behave as expected.

like image 77
MusiGenesis Avatar answered Nov 09 '22 21:11

MusiGenesis


With thanks to p-daddy in this question, I've 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);
}
like image 36
Simon Avatar answered Nov 09 '22 21:11

Simon


With Simon's solution I had the same Problem describt by Noam. With following code I've avoid the "Click through" 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();
        }
    }
}
like image 31
rkraen Avatar answered Nov 09 '22 19:11

rkraen


You should use Deactivate:
I have a form called Form2.
In the Deactivate section of the Properties window.
You declare the name Form2_Deactivate.
In the Form2.cs file:

private void Form2_Deactivate(object sender, EventArgs e)
{
    this.Close();
}
like image 34
Vương Hữu Thiện Avatar answered Nov 09 '22 19:11

Vương Hữu Thiện