Assigning the handlers within the button methods doesn't look right to me - you could add them multiple times and if those buttons are disabled then you'll never validate the inputs.
Here I present a simple form with two textboxes and a button. The button is disabled at the outset and only enabled when both textboxes have something in them
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
AddHandler TextBox1.TextChanged, AddressOf AllComplete
AddHandler TextBox2.TextChanged, AddressOf AllComplete
btnInsert.Enabled = False
End Sub
Private Sub TextBox1_Validating(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles TextBox1.Validating
If String.IsNullOrWhiteSpace(TextBox1.Text.Trim()) Then
e.Cancel = True
End If
End Sub
Private Sub TextBox2_Validating(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles TextBox2.Validating
If String.IsNullOrWhiteSpace(TextBox2.Text.Trim()) Then
e.Cancel = True
End If
End Sub
Private Sub AllComplete(ByVal sender As Object, ByVal e As EventArgs)
Dim validated As Boolean = Me.ValidateChildren()
btnInsert.Enabled = validated
End Sub
End Class
The key points here are:
- The checking for all of the controls being complete happens on the TextChanged event - thus the user must have at least attempted to enter some data before the button is enabled
- The
ValidateChildren()[
^] function will call all of the Validating events on the form (so don't call the
AllComplete
method from any Validating event!)
- If the user goes back to a control and deletes the contents after the button has been enabled it is disabled again.
I haven't used an ErrorProvider in this example because all that is doing is highlighting the control that is incorrect and adds nothing to the demonstration of the principle used here.
It is also worth noting that you can't close the form until data has been entered into all of the controls tested. You can get around that by adding the following code
Private Sub Form1_FormClosing(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing
e.Cancel = False
End Sub
More information on that problem can be found in (my tip)
Allow Form to close when invalid data is present[
^] but all you need is the code snippet above