1

I'm trying to collect up a number of text boxes and test against what is entered. I know this has been answered several times but most cases want to collect all the controls in a panel or form, I want to choose each text box.

I'm trying this, based on another stack overflow answer Loop through textboxes in vb.net but it not working for me. Null reference exception, which presumably I've not instantiated my object but I have I not, with the new keyword.... In summary why does this not work?

Dim boxes As New List(Of TextBox)() From {TextBox1, TextBox2, TextBox3, TextBox4, TextBox5}

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    TestTextBox()
End Sub

Private Sub TestTextBox()

For Each tb As TextBox In boxes
    If String.IsNullOrEmpty(tb.Text) Then
        MessageBox.Show("Text box is empty")
    ElseIf tb.Text.Length > 10 Then
        MessageBox.Show("Characters limited to 10")
    End If
Next

End Sub
Nick
  • 13
  • 2
  • 1
    Why do you need to test the length of the input when you can set the `MaxLength` of the `TextBox`? – John May 30 '22 at 02:14
  • 1
    That's not really the way to do validation in WinForms. You should handle the `Validating` event of each control and perform the validation there, setting `e.Cancel` to `True` if it fails. The user will then not be able to navigate away from the control until they enter valid data. You can then call `ValidateChildren` on the `Click` of the `Button` to validate all controls, including those that that never received focus. If that returns `True` then every control passed validation. – John May 30 '22 at 02:16
  • thanks for the replies, I'll check the validation out – Nick May 30 '22 at 20:46

1 Answers1

1

You get null list objects in the loop because you create a class collection and initialize it to add controls that haven't been created nor initialized yet. The boxes is created before the Form's constructor calls the InitializeComponent(); to create and initialize the hosted controls including the text boxes in question. So you need to wait for the controls to be created to access them.

Declare a List<TextBox>:

Public Class YourForm
    Private ReadOnly boxes As List(Of TextBox)

Then in the constructor, instantiate it and pass the elements:

    Sub New()
        InitializeComponent()
        boxes = New List(Of TextBox) From {TextBox1, TextBox2, TextBox3, TextBox4, TextBox5}
    End Sub
End Class

Side note, you can set the MaxLength property of the text boxes to be 10 and omit this ElseIf tb.Text.Length > 10 Then...

dr.null
  • 4,032
  • 3
  • 9
  • 12
  • thanks , its working now. As per the other comments it seem validation is the way to go, but I've accepted your answer. – Nick May 30 '22 at 20:56
  • @Nick You are welcome. [Here's](https://stackoverflow.com/a/65966553/14171304) another approach to validate controls of different types. If you just need to validate TextBox controls, then consider John's suggestion. – dr.null May 30 '22 at 22:56