0

I've created a VB.Net application which consists of a form and a series of classes. One class (GUI) contains all of the routines that handle the logic associated with the controls on my form. These controls are placed at design time.

My application runs in the system tray so I need to trap the FormClosing event so that the application is minimised rather than closed. Before moving everything into the GUI class my code worked but I'm now getting an error on this line:

Private Sub Monitor_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing

which is "Event 'FormClosing' cannot be found"

I'm completely stumped by this. I've changed changing the MyBase parameter to refer to the form by name, leaving it off and also adding:

Private WithEvents Monitor As System.Windows.Forms.Form

but none work.

EDIT: Here's a stripped down version of my GUI class containing the bits that handle minimising and restoring the form to the system tray

Note that there's no reference to the menu bar and menu items but VS doesn't complain about those.

Public Class GUI

' Make form controls accessible to this class (partial list only
' there's a lot of controls)
Private WithEvents tabControl As TabControl

Private WithEvents btn_status_start As Button
Private WithEvents btn_status_stop As Button
Private WithEvents btn_dataSource As Button

' **************************************************************************************
' *                                                                                    *
' * Control form behaviour so that it can be put into and taken from system tray       *
' *                                                                                    *
' **************************************************************************************

Private Sub cms_menu_exit_Click(sender As Object, e As EventArgs) Handles cms_menu_exit.Click
    ' Handles the saving and shutting down of the program

    ' Save any settings
    My.Settings.Save()

    ' Remove the icon
    Monitor.Dispose()

    ' Finally close the program
    Monitor.Close()

End Sub

Private Sub Notify_MouseDoubleClick(sender As Object, e As MouseEventArgs) Handles notify.MouseDoubleClick
    ' Code to restore the program window from the system tray when double clicked
    Me.Restore()
End Sub

Private Sub Notify_MouseClick(sender As Object, e As MouseEventArgs) Handles notify.MouseClick
    ' Code to restore the program window from the system tray when single clicked
    Me.Restore()
    Monitor.Focus()
End Sub

Private Sub Restore()
    If Monitor.WindowState = FormWindowState.Minimized Then
        Monitor.WindowState = FormWindowState.Normal
    End If
    Monitor.Visible = True
End Sub

Private Sub Monitor_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
    ' Catch the click on the X on the main form and set program to minimise instead
    If (e.CloseReason = CloseReason.UserClosing) Then
        e.Cancel = True
        Monitor.Hide()
    End If
End Sub

Private Sub cms_menu_open_Click(sender As Object, e As EventArgs) Handles cms_menu_open.Click
    ' Maximise the main form if selected
    Monitor.Show()
    Monitor.Focus()
End Sub

End Class

Philip Lee
  • 157
  • 3
  • 16
  • 1
    Could you show us some more code? This is to vague. Please show us the `FormClosing` event **inside** the class it is located in. At this point posting a little bigger block of code is not discouraged, as we have to see what's going on. – Visual Vincent Oct 02 '16 at 07:35
  • Added Vincent, hope it clarifies – Philip Lee Oct 02 '16 at 07:54
  • I don't see the `Monitor` variable anywhere. Also, is `GUI` just a normal class you've created yourself, or is it a form/UserControl? – Visual Vincent Oct 02 '16 at 08:02
  • _Monitor_ seems to be the name of the form class not an actual instance of it. Do you pass an instance of the Monitor form class or do you use the automatic instance of the Monitor class See: http://stackoverflow.com/questions/4698538/why-is-there-a-default-instance-of-every-form-in-vb-net-but-not-in-c – Steve Oct 02 '16 at 08:02
  • We have to see the class definition of the GUI class. It must derive from System.Windows.Forms.Form –  Oct 02 '16 at 08:08
  • @VisualVincent - Monitor is the name of the form that this GUI class handles. The GUI class is something that I've written myself. Steve - I'm not specifically passing anything so I guess it must be the later. Henrik Apart from the logic to handle the controls on the form that's all there is. – Philip Lee Oct 02 '16 at 08:14
  • You get this error when the VB compiler no longer knows that your class derives from Form. This will happen when you renamed the class name, there is a hidden file that still has the original name. A rough guess is that it was originally named "notify". Click the "Show All Files" icon in the Solution Explorer toolbar, now you can open the Designer.vb file and correct the class name there as well. Next time, right-click the class name and select "Rename". – Hans Passant Oct 02 '16 at 08:15
  • `MyBase` in this context refers to your `GUI` class (which's base is just `Class`, and it doesn't have a `FormClosing` event). If you want to handle a form's `FormClosing` event you have to specify which form instead of `MyBase`. If you always use the generic instance then `Monitor.FormClosing` should suffice. If you create new instances of the form, then you must pass that instance to your GUI class before you can handle its events. – Visual Vincent Oct 02 '16 at 08:21
  • I've already tried referring to it as Monitor.FormClosing but then get an error "Handle Clause requires a WithEvents variabel defined in the containing type or one of its base types". I had something similar with a Timer on the same form but got around that by adding "Private WithEvents timerScreenUpdate As System.Windows.Forms.Timer". I can't see how to get around this though ... – Philip Lee Oct 02 '16 at 09:22
  • 1
    I don't see in the code above any valid reason to have this class. Do you plan to handle the same events in more than one form? Then you should pass the instance of the form to handle. Do you plan to have more than one Monitor form? Then you should pass the instance of the specific form to handle. Beside the logic you handle here belongs to the form class itself, it makes little sense to have a GUI class for these. – Steve Oct 02 '16 at 09:33
  • I have one form and around 8 classes dedicated to different tasks. It's a multi-threaded app with lots going so I've created the GUI class to contain all code related to the GUI. In this way I have a very small Form1 and all the other code in discrete classes to aid maintainability ... – Philip Lee Oct 02 '16 at 09:41
  • Multi-threaded app? Another compelling reason to avoid default form instances. http://jmcilhinney.blogspot.it/2009/07/vbnet-default-form-instances.html – Steve Oct 02 '16 at 09:59
  • OK thanks for that article - interesting. Back to the drawing board I guess – Philip Lee Oct 02 '16 at 10:47
  • You dont need a class to handle form events for you. A Form **is** a class, so this just results in an inner-platform – Ňɏssa Pøngjǣrdenlarp Oct 02 '16 at 10:48

0 Answers0