Frusterated...

Should be simple. I have several forms that all do the same thing and I re-use the same basic code in all of them. But this one form is pitching a fit.

I have a DataGridView that is able to read data I have saved in a local DB. No problems there.

When I click a column, all the records populate the text boxes in the form just fine, except the very last record. It refuses.

Here's a snippet of code. I re-use this code in three other scenerios, and have no issues at all.

   Private Sub DataGridView1_CellClick(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellClick

        '// Open the form in the first tab.
        frmImpound.Show()
        frmImpound.TabControl1.SelectedIndex = 0

        '// DRIVER TAB
        frmImpound.lblRev.Text = DataGridView1.Item(0, e.RowIndex).Value.ToString
        frmImpound.txt_agency_case_number.Text = DataGridView1.Item(1, e.RowIndex).Value.ToString
        frmImpound.txt_subj_surname.Text = DataGridView1.Item(2, e.RowIndex).Value.ToString
        frmImpound.txt_subj_givenname.Text = DataGridView1.Item(3, e.RowIndex).Value.ToString
        frmImpound.txt_subj_street_address.Text = DataGridView1.Item(4, e.RowIndex).Value.ToString
        frmImpound.txt_subj_city.Text = DataGridView1.Item(5, e.RowIndex).Value.ToString
        frmImpound.txt_subj_state.Text = DataGridView1.Item(6, e.RowIndex).Value.ToString
        frmImpound.txt_subj_postal_code.Text = DataGridView1.Item(7, e.RowIndex).Value.ToString

        '// ========== all the way down to this part ================

        If DataGridView1.Item(52, e.RowIndex).Value.ToString = "1" Then
            frmImpound.cbOther2.Checked = True
        End If

        frmImpound.txt_vehicle_property.Text = DataGridView1.Item(53, e.RowIndex).Value.ToString
        frmImpound.txt_vehicle_damage.Text = DataGridView1.Item(54, e.RowIndex).Value.ToString
        frmImpound.txtOfficer.Text = DataGridView1.Item(55, e.RowIndex).Value.ToString
        frmImpound.txtAgency.Text = DataGridView1.Item(56, e.RowIndex).Value.ToString
        frmImpound.txtORI.Text = DataGridView1.Item(57, e.RowIndex).Value.ToString
        frmImpound.txtID.Text = DataGridView1.Item(58, e.RowIndex).Value.ToString

        '// THE LINE BELOW GIVES THE ERROR, ROW #59
        frmImpound.txtImpoundNumber.Text = DataGridView1.Item(59, e.RowIndex).Value.ToString

        Me.Close()

    End Sub

Row #59 gives the following:

Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index

I don't get it, because my index starts at 0 and climbs to 59. When I comment out row #59, my form populates just fine. This last row is causing a problem, I don't know why. Same type of code works fine elsewhere.

Does anyone see anything wrong here? I'm sure there is, I'm not the greatest programmer in the world.

If you step through the code, what is the value of e.Index on Rows 58 & 59?

You should use a loop for that incremental count too. You'd have to put the textboxes into an array in the order you want them filled in, then just loop 0 to 59.

Something like:

Dim myTextBoxes() As string = {frmImpound.lblRev.Text, _
                                frmImpound.txt_agency_case_number.Text, _
                                frmImpound.txtImpoundNumber}

For i As Integer = 0 To UBound(myTextBoxes)
    While i < DataGridView1.Rows.Count
        myTextBoxes(i).Text = DataGridView1.Item(i, e.RowIndex).Value.ToString
        If i = 52 AndAlso DataGridView1.Item(i, e.RowIndex).Value.ToString = "1" _
                                            Then frmImpound.cbOther2.Checked = True
        ' debug line here, to see where we're at with that index issue
        If i = 58 
            Debug.Print DataGridView1.Rows.Count
            Debug.Print e.RowIndex
        End If
    End While
Next
Comments
Awesome, thanks

Awesome, thanks for the snippet. I need some help with the loop. I'm not a pro like you guys, I'm a simple cop trying to piece something together for my co workers.

Anyways, the loop. I understand the simple text boxes (i think).

Dim myTextBoxes() As String = {frmImpound.lblRev.Text, _
                                       frmImpound.txt_agency_case_number.Text, _
                                       frmImpound.txt_subj_surname.Text, _
                                       frmImpound.txt_subj_givenname.Text, _
                                       frmImpound.txt_subj_street_address.Text, _
                                       frmImpound.txt_subj_city.Text, _
                                       frmImpound.txt_subj_state.Text, _
                                       frmImpound.txt_subj_postal_code.Text, _
                                       frmImpound.txt_driver_surname.Text, _
                                       frmImpound.txt_driver_givenname.Text, _
                                       frmImpound.txt_driver_street_address.Text}

My old code goes like this in a few spots- a checkbox, then a textbox, back to a checkbox, etc.

 If DataGridView1.Item(42, e.RowIndex).Value.ToString = "1" Then
            frmImpound.cbPossibleTheft.Checked = True
        End If

        If DataGridView1.Item(43, e.RowIndex).Value.ToString = "1" Then
            frmImpound.cbSpeedContest.Checked = True
        End If


        frmImpound.txt_impound_remarks.Text = DataGridView1.Item(44, e.RowIndex).Value.ToString
        frmImpound.txt_other_reason_impound.Text = DataGridView1.Item(45, e.RowIndex).Value.ToString
        frmImpound.cmbStateTax.Text = DataGridView1.Item(46, e.RowIndex).Value.ToString

        If DataGridView1.Item(47, e.RowIndex).Value.ToString = "1" Then
            frmImpound.cbNCIC.Checked = True
        End If


        If DataGridView1.Item(48, e.RowIndex).Value.ToString = "1" Then
            frmImpound.cbRadio.Checked = True
        End If

SO I'm having trouble going back and forth with this loop between the textboxes and the checkboxes.

                                       frmImpound.txt_impound_date_time.Text, _
                                       frmImpound.txt_time_of_impound.Text}

        For i As Integer = 0 To UBound(myTextBoxes)
            While i < DataGridView1.Rows.Count
                myTextBoxes(i) = DataGridView1.Item(i, e.RowIndex).Value.ToString


                If i = 30 AndAlso DataGridView1.Item(i, e.RowIndex).Value.ToString = "1" _
                        Then frmImpound.cbRelease.Checked = True

                {frmImpound.cmbTowingCompany.Text}


                If i = 32 AndAlso DataGridView1.Item(i, e.RowIndex).Value.ToString = "1" _
                        Then frmImpound.cbNoUtahRegistration.Checked = True

                                       If i = 58 Then
                Debug.Print(DataGridView1.Rows.Count)
                Debug.Print(e.RowIndex)
            End If
        End While
    Next

I hope my delimma makes sense.

I'm a simple cop trying to piece something together

we can tell... :) it's all good though.

You're actually doing a good job clearly labeling the textboxes - I can tell at a glance what they mean - props to you

SO I'm having trouble going back and forth with this loop between the textboxes and the checkboxes.

If you have moe than one or two of those CheckBox statements, you shold put all the checkbox code after the loop finishes, best practice is to let the loop do it's thing, and then set the other controls afterward.

If there are enough of those DataGrid value checks (say 3 or more), another array or a dictionary/list would be less code to write, even better would be to enfold that logic into the array loop or use a dictionary with named keys. Post your whole textbox/datagrid code block - we'll take a look at putting it into a dictionary.

FYI, the main difference between a dictionary and an array is that arrays store a range of objects accessed randomly by index - a Dictionary/List stores a range of key/value pairs. So in your case we would code the dictionary somewhat like this:

DISCLAIMER
This is untested code, it is entirely likely there are logic errors in here that will
put you in an infinite loop! Code for demo purposes only!

Private Sub DataGridView1_CellClick(ByVal sender As Object, _
                        ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) _
                        Handles DataGridView1.CellClick
        Try
            Dim myTextBoxDictionary As Dictionary(Of TextBox, String)
            '
            ' NOTE: This is a code revision, previous example used array of strings
            ' this also means that the Label controls will have to be handled separately
            '
            ' frmImpound.lblRev for example 
            '
        Dim myTextBoxes() As TextBox = {frmImpound.txt_agency_case_number.Text, _
                                        frmImpound.txt_subj_surname.Text(", _")
                                        frmImpound.txt_subj_givenname.Text, _
                                        frmImpound.txt_subj_street_address.Text, _
                                        frmImpound.txt_subj_city.Text, _
                                        frmImpound.txt_subj_state.Text, _
                                        frmImpound.txt_subj_postal_code.Text, _
                                        frmImpound.txt_driver_surname.Text, _
                                        frmImpound.txt_driver_givenname.Text, _
                                        frmImpound.txt_driver_street_address.Text}

            'Assumes textboxes and datagrid are in a determinate relationship
            ' i.e., one-to-one correlation where the first textbox will **always**
            ' be assigned the value of the indexed DataGrid Cell
            Dim i As Integer = 0
            '
            ' NOTE: while loop moved outside of For loop
            ' logic error on my part, doh!
            '
            ' dgv.Rows.Count starts at 1, dgv.Rows(index) starts at 0
            ' use less than since our counter starts at 0
            While i < DataGridView1.Rows.Count
                For i As Integer = 0 To (UBound(myTextBoxes))
                    With myTextBoxDictionary
                        ' sanity check, make sure we don't have a duplicate key
                        If Not .ContainsKey(myTextBoxDictionary(i)) Then
                            .Add(myTextBoxes(i), DataGridView1.Item(i, _
                                                        e.RowIndex).Value.ToString)
                        End If
                    End WIth
                Next
            End While
            ' then to access the value pairs and set the textbox.text properties
            For Each myTB As TextBox In Me.Controls.OfType(TypeOf TextBox)
                If myTextBoxDictionary.ContainsKey(myTB) Then
                    Dim myVal As String = myTextBoxDictionary.Item(myTB).ToString
                    myTB.Text = myVal
                End If
            Next
            ' then to set the Checkbox values
            ' this could get "kludgy" if there are a lot of checkboxes
            With myTextBoxDictionary
                If .ContainsKey(YOUR_CHECKBOX_NAME) Then
                    If .Item(YOUR_CHECKBOX_NAME).ToString = "VALUE_TO_CHECK" Then
                        YOUR_CHECKBOX.Checked = True
                    End If
                End If
            End With

        Catch ex As Exception
            MsgBox(ex.Message)
        End Try

 End Sub

Disregard the While and End While statements on Lines 33 & 43 - bad control logic.
Apparently not enough coffee this morning.. :)

John,

Thanks for the code. I need to do some reading on loops and arrays, so I can take your foundation and build on it. I don't want to leave this thread opened as unsolved, so I'll mark it solved, and work on this over the next while. I'll use your suggestions once I get these basics down better.

Thanks again.

If you're not constrained by any privacy, security, or intellectual property concerns - post that section of the code in it's entirety. I could use the practice anyway... :)

Oh, and were you able to solve your index out of range issue?

Edited 4 Years Ago by john.knapp

PM Sent.

    Private Sub DataGridView1_CellClick(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellClick

        '// Open the form in the first tab.
        frmImpound.Show()
        frmImpound.TabControl1.SelectedIndex = 0


            '// DRIVER TAB
            frmImpound.lblRev.Text = DataGridView1.Item(0, e.RowIndex).Value.ToString
            frmImpound.txt_agency_case_number.Text = DataGridView1.Item(1, e.RowIndex).Value.ToString
            frmImpound.txt_subj_surname.Text = DataGridView1.Item(2, e.RowIndex).Value.ToString
            frmImpound.txt_subj_givenname.Text = DataGridView1.Item(3, e.RowIndex).Value.ToString
            frmImpound.txt_subj_street_address.Text = DataGridView1.Item(4, e.RowIndex).Value.ToString
            frmImpound.txt_subj_city.Text = DataGridView1.Item(5, e.RowIndex).Value.ToString
            frmImpound.txt_subj_state.Text = DataGridView1.Item(6, e.RowIndex).Value.ToString
            frmImpound.txt_subj_postal_code.Text = DataGridView1.Item(7, e.RowIndex).Value.ToString

            frmImpound.txt_driver_surname.Text = DataGridView1.Item(8, e.RowIndex).Value.ToString
            frmImpound.txt_driver_givenname.Text = DataGridView1.Item(9, e.RowIndex).Value.ToString
            frmImpound.txt_driver_street_address.Text = DataGridView1.Item(10, e.RowIndex).Value.ToString
            frmImpound.txt_driver_city.Text = DataGridView1.Item(11, e.RowIndex).Value.ToString
            frmImpound.txt_driver_state.Text = DataGridView1.Item(12, e.RowIndex).Value.ToString
            frmImpound.txt_driver_postal_code.Text = DataGridView1.Item(13, e.RowIndex).Value.ToString

            frmImpound.txt_vehicle_plate.Text = DataGridView1.Item(14, e.RowIndex).Value.ToString
            frmImpound.txt_subj_state_plate.Text = DataGridView1.Item(15, e.RowIndex).Value.ToString
            frmImpound.txt_vehicle_expiration_date.Text = DataGridView1.Item(16, e.RowIndex).Value.ToString
            frmImpound.txt_vehicle_decal.Text = DataGridView1.Item(17, e.RowIndex).Value.ToString
            frmImpound.txt_vehicle_style.Text = DataGridView1.Item(18, e.RowIndex).Value.ToString
            frmImpound.txt_vehicle_year.Text = DataGridView1.Item(19, e.RowIndex).Value.ToString
            frmImpound.txt_vehicle_make.Text = DataGridView1.Item(20, e.RowIndex).Value.ToString
            frmImpound.txt_vehicle_model.Text = DataGridView1.Item(21, e.RowIndex).Value.ToString
            frmImpound.txt_vehicle_color.Text = DataGridView1.Item(22, e.RowIndex).Value.ToString
            frmImpound.txt_vehicle_decal_year.Text = DataGridView1.Item(23, e.RowIndex).Value.ToString
            frmImpound.txt_vehicle_vin.Text = DataGridView1.Item(24, e.RowIndex).Value.ToString
            frmImpound.txt_vehicle_odometer.Text = DataGridView1.Item(25, e.RowIndex).Value.ToString

            frmImpound.txt_arrestlocation.Text = DataGridView1.Item(26, e.RowIndex).Value.ToString
            frmImpound.txt_cite_no.Text = DataGridView1.Item(27, e.RowIndex).Value.ToString
            frmImpound.txt_impound_date_time.Text = DataGridView1.Item(28, e.RowIndex).Value.ToString
            frmImpound.txt_time_of_impound.Text = DataGridView1.Item(29, e.RowIndex).Value.ToString

            If DataGridView1.Item(30, e.RowIndex).Value.ToString = "1" Then
                frmImpound.cbRelease.Checked = True
            End If

            frmImpound.txt_date_of_citation.Text = DataGridView1.Item(31, e.RowIndex).Value.ToString
            frmImpound.cmbTowingCompany.Text = DataGridView1.Item(32, e.RowIndex).Value.ToString

            If DataGridView1.Item(33, e.RowIndex).Value.ToString = "1" Then
                frmImpound.cbNoUtahRegistration.Checked = True
            End If

            If DataGridView1.Item(34, e.RowIndex).Value.ToString = "1" Then
                frmImpound.cbReportedTheft.Checked = True
            End If

            If DataGridView1.Item(35, e.RowIndex).Value.ToString = "1" Then
                frmImpound.cbExpiredRegistration.Checked = True
            End If

            If DataGridView1.Item(36, e.RowIndex).Value.ToString = "1" Then
                frmImpound.cbAbandoned.Checked = True
            End If

            If DataGridView1.Item(37, e.RowIndex).Value.ToString = "1" Then
                frmImpound.cbImproperRegistration.Checked = True
            End If

            If DataGridView1.Item(38, e.RowIndex).Value.ToString = "1" Then
                frmImpound.cbTheft.Checked = True
            End If

            If DataGridView1.Item(39, e.RowIndex).Value.ToString = "1" Then
                frmImpound.cbNoInsurance.Checked = True
            End If

            If DataGridView1.Item(40, e.RowIndex).Value.ToString = "1" Then
                frmImpound.cbDUI.Checked = True
            End If

            If DataGridView1.Item(41, e.RowIndex).Value.ToString = "1" Then
                frmImpound.cbOther.Checked = True
            End If

            If DataGridView1.Item(42, e.RowIndex).Value.ToString = "1" Then
                frmImpound.cbInterlock.Checked = True
            End If

            If DataGridView1.Item(43, e.RowIndex).Value.ToString = "1" Then
                frmImpound.cbPossibleTheft.Checked = True
            End If

            If DataGridView1.Item(44, e.RowIndex).Value.ToString = "1" Then
                frmImpound.cbSpeedContest.Checked = True
            End If

            frmImpound.txt_impound_remarks.Text = DataGridView1.Item(45, e.RowIndex).Value.ToString
            frmImpound.txt_other_reason_impound.Text = DataGridView1.Item(46, e.RowIndex).Value.ToString
            frmImpound.cmbStateTax.Text = DataGridView1.Item(47, e.RowIndex).Value.ToString

            If DataGridView1.Item(48, e.RowIndex).Value.ToString = "1" Then
                frmImpound.cbNCIC.Checked = True
            End If

            If DataGridView1.Item(49, e.RowIndex).Value.ToString = "1" Then
                frmImpound.cbRadio.Checked = True
            End If

            If DataGridView1.Item(50, e.RowIndex).Value.ToString = "1" Then
                frmImpound.cbHubcaps.Checked = True
            End If

            If DataGridView1.Item(51, e.RowIndex).Value.ToString = "1" Then
                frmImpound.cbMats.Checked = True
            End If

            If DataGridView1.Item(52, e.RowIndex).Value.ToString = "1" Then
                frmImpound.cbMirrors.Checked = True
            End If

            If DataGridView1.Item(53, e.RowIndex).Value.ToString = "1" Then
                frmImpound.cbOther2.Checked = True
            End If

            frmImpound.txt_vehicle_property.Text = DataGridView1.Item(54, e.RowIndex).Value.ToString
            frmImpound.txt_vehicle_damage.Text = DataGridView1.Item(55, e.RowIndex).Value.ToString
            frmImpound.txtOfficer.Text = DataGridView1.Item(56, e.RowIndex).Value.ToString
            frmImpound.txtAgency.Text = DataGridView1.Item(57, e.RowIndex).Value.ToString
            frmImpound.txtORI.Text = DataGridView1.Item(58, e.RowIndex).Value.ToString
            frmImpound.txtID.Text = DataGridView1.Item(59, e.RowIndex).Value.ToString
            frmImpound.txtImpoundNumber.Text = DataGridView1.Item(60, e.RowIndex).Value.ToString

        Me.Close()

    End Sub

Will post updated loop code in this thread for posterity... :)

FYI, for anyone following this thread, perliminary testing indicates that the SystemIndexException was generated by a call to an external Function in another module.

This question has already been answered. Start a new discussion instead.