Reputation: 12087
I have a form declared as s property WithEvents
. If I add Handles formServers.FormClosing
to a Sub
declaration it works fine, but when I want to handle an event of a control within formServers
I get the following error -
'Handles' in classes must specify a 'WithEvents' variable.
How do I correctly set this up? Thanks.
Private WithEvents formServers As New formServers
Private Sub txtServers_Closing(ByVal Sender As Object,
ByVal e As EventArgs) Handles formServers.txtServers.LostFocus
Me.SetServers()
If Me.ServersError Then
Dim Ex As New Exception("Error validating Servers.")
Dim ErrorForm = New formError(Ex, 101)
End If
End Sub
Upvotes: 1
Views: 2865
Reputation: 43743
The problem is that you do are not specifying WithEvents
on the TextBox
. Rather, you are specifying WithEvents
on the Form
. You can only use Handles
on variables which you have declared directly with the WithEvents
keyword. With the WithEvents
being on the form, you will only be able to use Handles
to handle events that are raised directly by the form itself. You will not be able to do so for events raised by any of its controls.
You can fix this in one of two ways. Either you can use AddHandler
to register your event handler (rather than using the Handles
keyword), or you can create a TextBox
variable WithEvents
and then set it to the appropriate TextBox
object on the form, like this.
Private formInstance As New FormServers
Private WithEvents txtServers As TextBox
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
txtServers = formServers.txtServers
End Sub
Private Sub txtServers_LostFocus(Sender As Object, e As EventArgs) Handles txtServers.LostFocus
' ...
End Sub
The advantage of the latter approach, besides the more consistent, and possibly more elegant syntax, is that you don't have to remember to call RemoveHandler
.
Upvotes: 1
Reputation: 942338
The error message is fairly misleading. The Handles keyword has several restrictions, it cannot work across different classes, it needs an object reference. You must use the more universal AddHandler keyword instead.
There are some additional problems in your scenario. Never use the LostFocus event, use Leave instead. And it is very important that you subscribe the event for the specific instance of the form, using As New
gets you into trouble when you display the form multiple times, an ObjectDisposedException will be the outcome. Correct code looks like this:
Private formInstance As FormServers
Private Sub DisplayFormServer()
formInstance = new FormServers
AddHandler formInstance.txtServers.Leave, AddressOf txtServers_Closing
AddHandler formInstance.FormClosed, _
Sub()
formInstance = Nothing
End Sub
formInstance.Show()
End Sub
A much more elegant approach is to expose the event explicitly in your FormServers class. Make that look like this:
Public Class FormServers
Public Event ServersLeave As EventHandler
Private Sub txtServers_Leave(sender As Object, e As EventArgs) Handles txtServers.Leave
RaiseEvent ServersLeave(Me, EventArgs.Empty)
End Sub
End Class
Upvotes: 3