1

I wish in my code to handle the case when the red X at the upper right of the form is clicked. To this end I consulted this and created an event handler thus:-

Private Sub DoFoo (sender As System.Object, e As System.EventArgs) _
                   Handles Me.FormClosing
    ' Do things
End Sub

but I have found (from setting breakpoints) that on certain forms this event handler is not invoked when the red X is clicked, whereas on others it is. The forms are all of type System.Windows.Forms.Form but naturally are different in most respects. Does anyone know what might be causing this and what to do about it?

Edit

In answer to Vitor's question, the form that isn't working is created thus:-

If my_form Is Nothing Then
    my_form = New MyForm(parameters)
    my_form.Title = "Contour Plot Options"
Else
    my_form.BringToFront
End If

my_form.Show

Those that are behaving as expected are created like this:-

If my_working_form Is Nothing Then
    my_working_form = New MyWorkingForm
End If

my_working_form.Show

I can't see any Visible property to set or clear anywhere.

Brian Hooper
  • 21,544
  • 24
  • 88
  • 139

2 Answers2

3

Your parameters aren't quite right. A FormClosing event has a FormClosingEventArgs argument:

Private Sub DoFoo(ByVal sender As Object, ByVal e As FormClosingEventArgs) _
                  Handles Me.FormClosing
    If (e.CloseReason = CloseReason.UserClosing) Then

    End If
End Sub

You can inspect the e variable for the property `CloseReason', which would include a UserClosing enum, which means the user closed the form.

Each form should handle its own FormClosing event. Instead of subscribing to the event, I find it better to just override it like this:

Protected Overrides Sub OnFormClosing(ByVal e As FormClosingEventArgs)
  If (e.CloseReason = CloseReason.UserClosing) Then

  End If
  MyBase.OnFormClosing(e)
End Sub
LarsTech
  • 80,625
  • 14
  • 153
  • 225
  • Why do you prefer overriding it rather than subscribing it? Personal preference or any other special reason? – Styxxy Nov 05 '12 at 21:58
  • @Styxxy Mostly preference, but events are generally to signal another class something happened, not for the class itself. Also see [Form_Load() event or Override OnLoad()](http://stackoverflow.com/q/3670806/719186). – LarsTech Nov 05 '12 at 22:11
1

If you are instantiating your form you need to remember to AddHandler for the event you want to subscribe to.

my_form = New MyForm(parameters)
my_form.Title = "Contour Plot Options"
AddHandler my_form.Closing, AddressOf MyForm_Closing

'...

Sub MyForm_Closing(s As Object, ByVal e As FormClosingEventArgs)
   '...
End Sub

Of course, to avoid memory leaks you should do it like this:

'global code
Private myFormClosingEventHandler As FormClosedEventHandler = Nothing
'...

Private Sub CreateForm
    my_form = New MyForm(parameters)
    my_form.Title = "Contour Plot Options"

    myFormClosingEvent = New FormClosedEventHandler(AddressOf MyForm_Closing)
    AddHandler my_form.Closing, myFormClosingEventHandler
    '...
End Sub

Sub MyForm_Closing(s As Object, ByVal e As FormClosingEventArgs)
    RemoveHandler my_form.Closing, myFormClosingEventHandler
   '...
End Sub

Alternatively you can have it all pre-initalized for you by doing this in your class instead:

Private WithEvents my_form1 As Form = New Form()
Private WithEvents my_form2 As Form = New Form()
'... etc.

Now you can add in your code handlers using the Handle keyword as usual without using the AddHandler and RemoveHandler.

Protected Sub my_form1_Closing(s as object, e as FormClosingEventArgs) _
    Handles my_form1.Closing
    '...
End Sub