Disable Button until multiple Textboxes got Validated - vb.net

I have a form with over 10 textboxes and 1 button, I would like to disable the button with a realtime validation until all textboxes filled with a 10 or a 13 length numeric value, my code is the following so far:
Private Sub Form1_Load(sender As Object, e As System.EventArgs) Handles Me.Load
For Each userID As Control In Me.Controls.OfType(Of TextBox)()
AddHandler userID.TextChanged, AddressOf ValidateAllFields
Next userID
End Sub
Private Sub userID_KeyPress(ByVal sender As Object, ByVal e As KeyPressEventArgs) Handles Me.KeyPress
If e.KeyChar <> ChrW(Keys.Back) Then
If Char.IsNumber(e.KeyChar) Then
Else
e.Handled = True
End If
End If
End Sub
Private Function ValidateAllFields()
Dim Validation As Boolean = True
For Each userID As Control In Me.Controls.OfType(Of TextBox)()
Dim e As New System.ComponentModel.CancelEventArgs
e.Cancel = False
Call userID_Validating(userID, e)
If e.Cancel = True Then Validation = False
Next userID
buttonSave.Enabled = Not Me.Controls.OfType(Of TextBox).Any(Function(userID) userID.Text.Length <> 10 AndAlso userID.Text.Length <> 13)
Return Validation
End Function
Private Sub userID_Validating(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles _
user00.Validating, _
user01.Validating, _
user02.Validating, _
user03.Validating, _
user04.Validating, _
user05.Validating, _
user06.Validating, _
user07.Validating, _
user07.Validating, _
user08.Validating, _
user09.Validating, _
user10.Validating, _
user11.Validating
If Not IsNumeric(sender.Text) OrElse (sender.Text.Length <> 10) AndAlso (sender.Text.Length <> 13) Then
ErrorProvider1.SetError(sender, "")
ErrorProvider2.SetError(sender, "Please enter a valid User ID.")
e.Cancel = True
Else
ErrorProvider1.SetError(sender, "Valid User ID.")
ErrorProvider2.SetError(sender, "")
End If
End Sub
Thanks to your help it works as I wanted, but can you help me improve/clean it? I'm still studying vb, I'm open to any suggestion. Thanks in advance!

Here you have a code performing the actions you want:
Dim done1, done2, done3 As Boolean
Dim targetLength1 As Integer = 10
Dim targetLength2 As Integer = 13
Private Sub TextBox1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged
Try
If (IsNumeric(TextBox1.Text)) Then
If (TextBox1.Text.Length = targetLength1 Or TextBox1.Text.Length = targetLength2) Then
done1 = True
End If
End If
If (done1 And done2 And done3) Then
Button1.Enabled = True
End If
Catch ex As Exception
End Try
End Sub
Private Sub TextBox2_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox2.TextChanged
Try
If (IsNumeric(TextBox2.Text)) Then
If (TextBox2.Text.Length = targetLength1 Or TextBox2.Text.Length = targetLength2) Then
done2 = True
End If
End If
If (done1 And done2 And done3) Then
Button1.Enabled = True
End If
Catch ex As Exception
End Try
End Sub
Private Sub TextBox3_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox3.TextChanged
Try
If (IsNumeric(TextBox3.Text)) Then
If (TextBox3.Text.Length = targetLength1 Or TextBox3.Text.Length = targetLength2) Then
done3 = True
End If
End If
If (done1 And done2 And done3) Then
Button1.Enabled = True
End If
Catch ex As Exception
End Try
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Button1.Enabled = False
End Sub
It accounts just for 3 textboxes (TextBox1, TextBox2 and TextBox3) and 1 button (Button1) but you can extend the idea to as many textboxes as you wish. It relies on the TextChanged even of each textbox. When the condition is met (given textbox has a number whose length is 10 or 13), the corresponding flag is set to true (e.g., done1 for TextBox1...). When all the flags are true (all the textboxes contain the expected information), the button is disabled.

I think would better to use TextChanged Event ..
Private Sub TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged, TextBox2.TextChanged, ....., TextBox10.TextChanged
Chk4ButtonEnabled()
End Sub
Sub Chk4ButtonEnabled()
Dim s as String
For Each userID As Control In Me.Controls
If userID.GetType Is GetType(TextBox) Then
s = userID.Text
If Not s.Length = 10 OR Not s.Length = 13 Then
ErrorProvider1.SetError(userID, "")
buttonSave.Enabled = False
Else
ErrorProvider1.SetError(userID, "Valid User ID.")
buttonSave.Enabled = True
End If
End If
Next
End Sub

Related

How to put many Textbox in one If else statement

This is the question
=If the FN button
will be click, then it will display a message base on the status of the textbox1 control. For the MN button, if
the event is click then it will display a message base on the status of the textbox2 control. The LN button
was clicked then it will display a message base on the status of the textbox3 control. Lastly, if the Clear
button control will be click and any of the textbox control is not empty then it will clear all the textbox
controls, but if all textbox controls are empty then it will show a message that all textbox controls are empty.
this is my code
Public Class Form1
Private Sub Label1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Label1.Click
Label1.Text = "First Name"
End Sub
Private Sub Label2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Label2.Click
Label2.Text = "Middle Name"
End Sub
Private Sub Label3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Label3.Click
Label3.Text = "Last Name"
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Button1.Text = "FN"
If TextBox1.Text = vbNullString Then
MessageBox.Show("The First name is empty")
Else MessageBox.Show("The First name is " & TextBox1.Text)
End If
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Button2.Text = "MN"
If TextBox2.Text = vbNullString Then
MessageBox.Show("The Middle name is empty")
Else : MessageBox.Show("The Middle name is " & TextBox2.Text)
End If
End Sub
Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
Button3.Text = "LN"
If TextBox3.Text = vbNullString Then
MessageBox.Show("The Last name is empty")
Else : MessageBox.Show("The Last name is " & TextBox3.Text)
End If
End Sub
Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click
Button4.Text = "Clear"
If (TextBox1.Text) And (TextBox2.Text) = vbNullString Then
MessageBox.Show("Textbox control is empty")
Else : TextBox1.Clear()
End If
For Each txt As Control In Me.Controls.OfType(Of TextBox)()
txt.Text = ""
Next
End Sub
Private Sub TextBox1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged
End Sub
Private Sub TextBox2_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox2.TextChanged
End Sub
End Class
My question is , how to work on clear button because i cant do it in Textbox2 and Textbox3 thankyou
Try something like this
For Each ctrl As Control In Me.Controls
If TypeOf ctrl Is TextBox Then
CType(ctrl, TextBox).Text = String.Empty
End If
Next ctrl
Try to add Next txt to your For Each
So, you are asking about Button4_Click.
This is what I was about to suggest first, because clearing all text boxes whether they are empty or not, is faster than first checking and then clearing.
Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click
' Button4.Text = "Clear"
' If (TextBox1.Text) And (TextBox2.Text) = vbNullString Then
' MessageBox.Show("Textbox control is empty")
' Else : TextBox1.Clear()
' End If
For Each txt As Control In Me.Controls.OfType(Of TextBox)()
txt.Text = ""
Next
MessageBox.Show("Textbox controls are empty")
End Sub
But then, if the intention is to a) just clear all textboxes, without any message if any one has some text. b) show the message only if all are empty.
Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click
' Button4.Text = "Clear"
If (TextBox1.Text = vbNullString) And (TextBox2.Text = vbNullString) And (TextBox3.Text = vbNullString) Then
MessageBox.Show("Textbox controls are empty")
Else
TextBox1.Text = ""
TextBox2.Text = ""
TextBox3.Text = ""
End If
or (if this works, VB6 is alien for me)
....
Else
For Each txt As Control In Me.Controls.OfType(Of TextBox)()
txt.Text = ""
Next
End If
End Sub
I'd use a List(Of TextBox) allowing you to leverage All and ForEach:
Public Class Form1
Private TBs As New List(Of TextBox)
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
TBs.AddRange({TextBox1, TextBox2, TextBox3})
End Sub
Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
If TBs.All(Function(tb) tb.Text = "") Then
MessageBox.Show("All TextBoxes are empty!")
Else
TBs.ForEach(Sub(tb) tb.Clear())
End If
End Sub
End Class
Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click
' Button4.Text = "Clear"
If (TextBox1.Text = vbNullString) And (TextBox2.Text = vbNullString) And (TextBox3.Text = vbNullString) Then
MessageBox.Show("Textbox controls are empty")
Else
TextBox1.Text = ""
TextBox2.Text = ""
TextBox3.Text = ""
End If
thanks sir Tom Brunberg, this code works for me :)

VB.NET How to avoid first key press when captured it as hotkey?

I managed to make my app capture any key to use it as a hotkey, but when I press the key the hotkey function is activated. This is what I have so far:
Private Sub tmrFunc_Tick(sender As Object, e As EventArgs) Handles tmrFunc.Tick
'Function
End Sub
Private Sub tmrKey_Tick(sender As Object, e As EventArgs) Handles tmrKey.Tick
'Uses the hotkey to start and stop tmrF
End Sub
Private Sub lblCapKey_Click(sender As Object, e As EventArgs) Handles lblCapKey.Click
tmrKey.Enabled = False
txtbStartFunc.Enabled = True
txtbStartFunc.Text = "Press any key"
txtbStartFunc.Focus()
End Sub
Private Sub txtbStartFunc_KeyDown(sender As Object, e As KeyEventArgs) Handles txtbStartFunc.KeyDown
If e.KeyCode = Keys.F10 Then
txtbStartFunc.Text = "F10"
End If
tmrKey.Enabled = True
txtbStartFunc.Enabled = False
End Sub
The current code perfectly captures the key and uses it as a hotkey, the problem is that the hotkey is activated on this first key pressed and that causes it to be activated unexpectedly at the wrong time.
My current goal is that the function is not activated with the first keystroke, but is activated with the following keystrokes.
I am expecting something like this:
Private Sub txtbStartFunc_KeyDown(sender As Object, e As KeyEventArgs) Handles txtbStartFunc.KeyDown
If e.KeyCode = Keys.F10 Then
txtbStartFunc.Text = "F10"
End If
tmrKey.Enabled = True
'=========================
tmrFunc.Enabled = False
'=========================
txtbStartFunc.Enabled = False
End Sub
Here's a solution that finally worked for me. It allows you to set the hotkeys between F1 and F10, but won't let you select the same key for both of them.
This is pretty different than what you had, so take your time studying it and ask as many questions as need be:
Public Class Form1
Private Const KeyDownBit As Integer = &H8000
Private Enum HotKeyType
StartClicker
StopClicker
End Enum
Private _StartHotkey As Keys
Private _StopHotKey As Keys
Private SelectingHotKey As HotKeyType
Private HotKeySelected As Boolean = False
Private _SettingHotKey As Boolean = False
Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vKeys As Integer) As Short
Private Property StartHotKey As Keys
Get
Return _StartHotkey
End Get
Set(value As Keys)
If value <> StopHotKey Then
_StartHotkey = value
TextBox1.Text = StartHotKey.ToString
End If
End Set
End Property
Private Property StopHotKey As Keys
Get
Return _StopHotKey
End Get
Set(value As Keys)
If value <> StartHotKey Then
_StopHotKey = value
TextBox2.Text = StopHotKey.ToString
End If
End Set
End Property
Private Property SettingHotKey As Boolean
Get
Return _SettingHotKey
End Get
Set(value As Boolean)
If value Then
HotKeySelected = False
Timer2.Stop()
Else
Timer2.Start()
End If
_SettingHotKey = value
End Set
End Property
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.KeyPreview = True
Timer1.Enabled = False
Timer2.Enabled = False
Timer1.Interval = 50
Timer2.Interval = 50
TextBox1.ReadOnly = True ' they just stay this way all the time
TextBox2.ReadOnly = True ' they just stay this way all the time
StartHotKey = Keys.F1
StopHotKey = Keys.F2
Timer2.Start()
End Sub
Private Sub Timer2_Tick(sender As Object, e As EventArgs) Handles Timer2.Tick
Dim startKeyDown, stopKeyDown As Boolean
GetAsyncKeyState(StartHotKey) ' disregard first call to "flush it"
startKeyDown = (GetAsyncKeyState(StartHotKey) And KeyDownBit) = KeyDownBit ' see if it's down
GetAsyncKeyState(StopHotKey) ' disregard first call to "flush it"
stopKeyDown = (GetAsyncKeyState(StopHotKey) And KeyDownBit) = KeyDownBit ' see if it's down
TextBox1.BackColor = If(startKeyDown, Color.Green, Control.DefaultBackColor)
TextBox2.BackColor = If(stopKeyDown, Color.Green, Control.DefaultBackColor)
If startKeyDown Then
Timer1.Start()
End If
If stopKeyDown Then ' if you hold both down, then it'll stop
Timer1.Stop()
Label1.BackColor = Control.DefaultBackColor
End If
End Sub
Private Sub BothButtons_Click(sender As Object, e As EventArgs) Handles Button1.Click, Button2.Click
SelectingHotKey = If(sender Is Button1, HotKeyType.StartClicker, HotKeyType.StopClicker)
SettingHotKey = True ' automatically turns off Timer2
Dim tb As TextBox = If(sender Is Button1, TextBox1, TextBox2)
tb.Text = "Press F1 to F10"
End Sub
Protected Overrides Function ProcessCmdKey(ByRef msg As Message, keyData As Keys) As Boolean
Select Case keyData
Case Keys.F1 To Keys.F10
If SettingHotKey Then
If SelectingHotKey = HotKeyType.StartClicker Then
If keyData <> StopHotKey Then
StartHotKey = keyData
HotKeySelected = True
Return True
End If
Else
If keyData <> StartHotKey Then
StopHotKey = keyData
HotKeySelected = True
Return True
End If
End If
End If
End Select
Return MyBase.ProcessCmdKey(msg, keyData)
End Function
Private Sub Form1_KeyUp(sender As Object, e As KeyEventArgs) Handles Me.KeyUp
If SettingHotKey AndAlso HotKeySelected Then
SettingHotKey = False ' restarts Timer2 once selected key has been released
End If
End Sub
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
Label1.BackColor = Color.Green
Label1.Text = DateTime.Now.ToString("HH:mm:ss.ffff") ' just to show it's "clicking"
End Sub
End Class
Okay, here's a little example of my program, which shows my problem.
This is the interface:
enter image description here
When I press F1, the counter starts to add 1 to itself, when I press F2, the counter stops. The Select button changes F1 to F9 or F2 to F10, but when I change the key the function is triggered, that is, if the counter is stopped, and the key is at F1, when I click Select to change from F1 to F9, the counter is activated.
Here is an example of the code, so you can see the problem first hand:
Public Class Form1
Declare Function GetAsyncKeyState Lib "user32" (ByVal vKeys As Integer) As Short
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
Label1.Text += 1
End Sub
Private Sub Timer2_Tick(sender As Object, e As EventArgs) Handles Timer2.Tick
Dim a, b As Boolean
If TextBox1.Text = "F1" Then
a = GetAsyncKeyState(Keys.F1)
ElseIf TextBox1.Text = "F9" Then
a = GetAsyncKeyState(Keys.F9)
End If
If TextBox2.Text = "F2" Then
b = GetAsyncKeyState(Keys.F2)
ElseIf TextBox2.Text = "F10" Then
b = GetAsyncKeyState(Keys.F10)
End If
If a = True Then
Timer1.Start()
ElseIf b = True Then
Timer1.Stop()
End If
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Timer2.Enabled = False
TextBox1.ReadOnly = False
TextBox1.Text = "Press any key"
TextBox1.Focus()
End Sub
Private Sub TextBox1_KeyDown(sender As Object, e As KeyEventArgs) Handles TextBox1.KeyDown
e.SuppressKeyPress = True
If TextBox1.ReadOnly = False Then
If e.KeyCode = Keys.F9 Then
TextBox1.Text = "F9"
Else
TextBox1.Text = "F1"
End If
End If
Timer2.Enabled = True
TextBox1.ReadOnly = True
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Timer2.Enabled = False
TextBox2.ReadOnly = False
TextBox2.Text = "Press any key"
TextBox2.Focus()
End Sub
Private Sub TextBox2_KeyDown(sender As Object, e As KeyEventArgs) Handles TextBox2.KeyDown
e.SuppressKeyPress = True
If TextBox2.ReadOnly = False Then
If e.KeyCode = Keys.F10 Then
TextBox2.Text = "F10"
Else
TextBox2.Text = "F2"
End If
End If
Timer2.Enabled = True
TextBox2.ReadOnly = True
End Sub
End Class
#Idle_Mind

combobox multiple thread error

I have a problem with my code. I keep getting Multiple thread Error with backgroundworker, because of the combobox item display. Please look at my code below its a very simple code which I am planning to use on big scale, all I want it to do is "If item "1" selected show item "1" in label1. I can only assume that problem exists because Combobox runs in different thread....
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
BackgroundWorker1.runworkerasync()
BackgroundWorker1.WorkerReportsProgress = True
Me.Cursor = Cursors.WaitCursor 'Cursor changes to wait
End Sub
Public Structure controlwithtext
Public controlname As Control
Public text As String
Public Sub New(ByVal ctrl As Control, ByVal text As String)
Me.controlname = ctrl
Me.text = text
End Sub
End Structure
Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As DoWorkEventArgs) Handles BackgroundWorker1.DoWork
If comboBox1.SelectedItem = "1" then
BackgroundWorker1.ReportProgress(5, New controlwithtext(Label1, ComboBox1.SelectedItem))
End If
End Sub
Private Sub SetBackgroundWorker_ProgressChanged(ByVal sender As Object,
ByVal e As ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
If TypeOf e.UserState Is controlwithtext Then
Dim cwt As controlwithtext = CType(e.UserState, controlwithtext)
cwt.controlname.Text = cwt.text
End If
End Sub
Here's an example of how to read from and write to controls from the BackgroundWorker thread:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
BackgroundWorker1.RunWorkerAsync()
End Sub
Private Sub BackgroundWorker1_DoWork(sender As Object, e As DoWorkEventArgs) Handles BackgroundWorker1.DoWork
While True
System.Threading.Thread.Sleep(250)
Dim selection As String = Me.Invoke(Function()
If Not IsNothing(ComboBox1.SelectedItem) Then
Return ComboBox1.SelectedItem.ToString
Else
Return String.Empty
End If
End Function).ToString
If selection = "1" Then
Me.Invoke(Sub()
Label1.Text = ComboBox1.SelectedItem.ToString
End Sub)
Else
Me.Invoke(Sub()
Label1.Text = "something else"
End Sub)
End If
End While
End Sub

VB.net stopping a backgroundworker

I want to create a button that could stop my background worker and end all the process it is working on.
Here is my sample backgroundworker code:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Try
If BackgroundWorker1.IsBusy <> True Then
BackgroundWorker1.RunWorkerAsync()
End If
Catch ex As Exception
End Try
End Sub
Private Sub BackgroundWorker1_DoWork(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Dim counter As Integer = 1
Do
'updated code with stop function----------------
BackgroundWorker1.WorkerSupportsCancellation = True
If BackgroundWorker1.CancellationPending Then
e.Cancel = True
ProgressBar1.Value = 0
Exit Do
End If
'updated code with stop function----------------
ListBox1.Items.Add(counter)
ProgressBar1.Value = ((counter - 1) / limit) * 100
counter = counter + 1
Loop While(counter <= 999999999999999999)
End Sub
Private Sub BackgroundWorker1_ProgressChanged(sender As System.Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
Try
Catch ex As Exception
End Try
End Sub
Private Sub BackgroundWorker1_Completed(sender As System.Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
Try
Catch ex As Exception
End Try
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = False
End Sub
'updated code with stop function----------------
Private Sub StopButton_Click(sender As Object, e As EventArgs) Handles StopButton.Click
If BackgroundWorker1.IsBusy Then
If BackgroundWorker1.WorkerSupportsCancellation Then
BackgroundWorker1.CancelAsync()
End If
End If
End Sub
'updated code with stop function----------------
I want to reset the loop and return the Progress Bar to 0% when i stop the backgroundworker.
Is this possible?
The code above has been updated and it is now working fine.
I have added this code inside my do loop:
BackgroundWorker1.WorkerSupportsCancellation = True
If BackgroundWorker1.CancellationPending Then
e.Cancel = True
ProgressBar1.Value = 0
Exit Do
End If
I created a button that stops the worker:
Private Sub StopButton_Click(sender As Object, e As EventArgs) Handles StopButton.Click
If BackgroundWorker1.IsBusy Then
If BackgroundWorker1.WorkerSupportsCancellation Then
BackgroundWorker1.CancelAsync()
End If
End If
End Sub
The Backgroundworker class has the method CancelAsync() which you need to call to cancel the execution of the bgw.
You need to set the Backgroundworker.WorkerSupportsCancellation property to true and inside the while loop you need to check the CancellationPending property wether the value is true which indicates a call to the CancelAsync() method.
If CancellationPending evaluates to true, you would ( which you should have done already ) call one of the overloaded ReportProgress() (Docu) methods to set your ProgressBar value to the desired value.
EDIT: You should set the Cancel property of the DoWorkEventArgs to true so you can check the Cancelled property of the RunWorkerCompletedEventArgs inside the RunworkerCompletedevent.
You also shouldn not access any controls which lives in the UI thread. You better use the ProgressChanged(Docu) event.
See: BackgroundWorker Docu
Public Class Form1
Private iVal As Integer = 0
Private Sub bgw_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bgw.DoWork
For iVal = iVal To 100 Step 1
bgw.ReportProgress(iVal)
Threading.Thread.Sleep(99)
If (bgw.CancellationPending = True) Then
e.Cancel = True
Exit For
End If
Next
End Sub
Private Sub bgw_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles bgw.ProgressChanged
pbar.Value = e.ProgressPercentage
lblProgrss.Text = e.ProgressPercentage.ToString() & "%"
End Sub
Private Sub bgw_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles bgw.RunWorkerCompleted
If (e.Cancelled = True) Then
pic.Visible = False
pbar.Value = iVal
lblProgrss.Text = iVal & "%"
btnstart.Text = "Start"
btnstart.BackColor = Color.Green
Else
pic.Visible = False
btnstart.Text = "Start"
btnstart.BackColor = Color.Green
iVal = 0
End If
End Sub
Private Sub btnstart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnstart.Click
If (btnstart.Text = "Start") Then
btnstart.Text = "Stop"
btnstart.BackColor = Color.Red
pic.Visible = True
bgw.RunWorkerAsync()
Else
If (bgw.IsBusy = True) Then
btnstart.Text = "Start"
btnstart.BackColor = Color.Green
bgw.CancelAsync()
End If
End If
End Sub
End Class

Get InvalidOperatorException was unhandled upon compiling

Everything was compiling just fine until validation for text fields was implemented.
Why won't it compile?
An error occurred creating the form.
See Exception.InnerException for
details. The error is: External
component has thrown an exception.
The source:
Public Class frmAddStudent
Dim aryData(6) As String
Public Shared newStudentRecord As String
Private Sub btnCancel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCancel.Click
Me.DialogResult = DialogResult.Cancel
End Sub
Private Sub btnAddStudent_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAddStudent.Click
'place all the student field data into the array of elements
aryData(0) = txtFirstName.Text
aryData(1) = txtLastName.Text
aryData(2) = txtMajor.Text
aryData(3) = txtPhone.Text
aryData(4) = txtEmail.Text
aryData(5) = txtGPA.Text
'join the array elements and place the result into a string variable
newStudentRecord = Join(aryData, " ")
'create a link between the form and the file with streamwriter and write to the text file
If System.IO.File.Exists(frmMain.FILE_NAME) = True Then
Dim objWriter As New System.IO.StreamWriter(frmMain.FILE_NAME, True)
objWriter.WriteLine(newStudentRecord)
objWriter.Close()
End If
Me.DialogResult = DialogResult.OK
End Sub
Private Sub txtFirstName_Validating(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles txtFirstName.Validating
If txtFirstName.Text.Contains(" ") Or txtFirstName.Text.Length = 0 Or Not System.Text.RegularExpressions.Regex.IsMatch(txtFirstName.Text, "[a-z|A-Z]+$") Then
ErrorProvider1.SetError(txtFirstName, "First Name can't contain spaces or be of zero length and must consist of only letters")
e.Cancel = True
Else
ErrorProvider1.SetError(txtFirstName, "")
End If
End Sub
Private Sub frmAddStudent_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
ErrorProvider1.BlinkStyle = ErrorBlinkStyle.NeverBlink
End Sub
Private Sub txtLastName_Validating(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles txtLastName.Validating
If txtLastName.Text.Contains(" ") Or txtLastName.Text.Length = 0 Or Not System.Text.RegularExpressions.Regex.IsMatch(txtLastName.Text, "[a-z|A-Z]+$") Then
ErrorProvider1.SetError(txtLastName, "Last Name can't contain spaces or be of zero length and must consist of only letters")
e.Cancel = True
Else
ErrorProvider1.SetError(txtLastName, "")
End If
End Sub
Private Sub txtMajor_Validating(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles txtMajor.Validating
If txtMajor.Text.Length > 0 Then
If Not System.Text.RegularExpressions.Regex.IsMatch(Strings.Left(txtMajor.Text, 1), "[a-z|A-Z]+$") Then
ErrorProvider1.SetError(txtMajor, "Major course code is incorrect")
Else
ErrorProvider1.SetError(txtMajor, "")
End If
Else
ErrorProvider1.SetError(txtMajor, "Major cant' be zero length")
End If
End Sub
End Class
EDIT: Here's also a link to a PrtSc of the problem: http://img88.imageshack.us/i/imageqc.gif/